Merge pull request #14832 from HugoHo0212/master
Some changes to INSTALL.md to make it more concise and clear
diff --git a/.clang-format b/.clang-format
index 3b24519..f9af763 100644
--- a/.clang-format
+++ b/.clang-format
@@ -3,5 +3,10 @@
BasedOnStyle: Google
DerivePointerAlignment: false
PointerAlignment: Left
+---
+Language: ObjC
+BasedOnStyle: Google
+ColumnLimit: 100
+ObjCBlockIndentWidth: 2
...
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index fb6f98c..12f46d1 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -4,6 +4,6 @@
/**/OWNERS @markdroth @nicolasnoble @a11r
/bazel/** @nicolasnoble @dgquintas @a11r @vjpai
/cmake/** @jtattermusch @nicolasnoble @matt-kwong
-/src/core/ext/filters/client_channel/** @markdroth @dgquintas @a11r
+/src/core/ext/filters/client_channel/** @markdroth @dgquintas @AspirinSJL
/tools/dockerfile/** @jtattermusch @matt-kwong @nicolasnoble
/tools/run_tests/performance/** @ncteisen @matt-kwong @jtattermusch
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
index 24587a5..5b2ac80 100644
--- a/.github/ISSUE_TEMPLATE.md
+++ b/.github/ISSUE_TEMPLATE.md
@@ -1,12 +1,12 @@
-Please answer these questions before submitting your issue.
-
-### Should this be an issue in the gRPC issue tracker?
-
-Create new issues for bugs and feature requests. An issue needs to be actionable. General gRPC discussions and usage questions belong to:
-- [grpc.io mailing list](https://groups.google.com/forum/#!forum/grpc-io)
-- [StackOverflow, with `grpc` tag](http://stackoverflow.com/questions/tagged/grpc)
-
-*Please don't double post your questions in more locations; we are monitoring both channels, and the time spent de-duplicating questions is better spent answering more user questions.*
+<!--
+
+This form is for bug reports and feature requests ONLY!
+For general questions and troubleshooting, please ask/look for answers here:
+- grpc.io mailing list: https://groups.google.com/forum/#!forum/grpc-io
+- StackOverflow, with "grpc" tag: http://stackoverflow.com/questions/tagged/grpc
+
+Issues specific to *grpc-java*, *grpc-go*, *grpc-node*, *grpc-dart*, *grpc-web* should be created in the repository they belong to (e.g. https://github.com/grpc/grpc-LANGUAGE/issues/new)
+-->
### What version of gRPC and what language are you using?
diff --git a/.gitignore b/.gitignore
index 0f3cd78..cde82bc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,8 +15,10 @@
htmlcov/
dist/
*.egg
-py27/
-py3[0-9]*/
+py27_gevent/
+py27_native/
+py3[0-9]_gevent/
+py3[0-9]_native/
# Node installation output
node_modules
diff --git a/.pylintrc-tests b/.pylintrc-tests
new file mode 100644
index 0000000..b358b2c
--- /dev/null
+++ b/.pylintrc-tests
@@ -0,0 +1,108 @@
+[VARIABLES]
+
+# TODO(https://github.com/PyCQA/pylint/issues/1345): How does the inspection
+# not include "unused_" and "ignored_" by default?
+dummy-variables-rgx=^ignored_|^unused_
+
+[DESIGN]
+
+# NOTE(nathaniel): Not particularly attached to this value; it just seems to
+# be what works for us at the moment (excepting the dead-code-walking Beta
+# API).
+max-args=6
+
+[MISCELLANEOUS]
+
+# NOTE(nathaniel): We are big fans of "TODO(<issue link>): " and
+# "NOTE(<username or issue link>): ". We do not allow "TODO:",
+# "TODO(<username>):", "FIXME:", or anything else.
+notes=FIXME,XXX
+
+[MESSAGES CONTROL]
+
+disable=
+ # These suppressions are specific to tests:
+ #
+ # TODO(https://github.com/grpc/grpc/issues/261): investigate
+ # each of the following one by one and consider eliminating
+ # the suppression category.
+ # Eventually, the hope is to eliminate the .pylintrc-tests
+ # altogether and rely on .pylintrc for everything.
+ pointless-statement,
+ no-member,
+ no-self-use,
+ attribute-defined-outside-init,
+ unused-argument,
+ unused-variable,
+ unused-import,
+ redefined-builtin,
+ too-many-public-methods,
+ too-many-locals,
+ redefined-variable-type,
+ redefined-outer-name,
+ ungrouped-imports,
+ too-many-branches,
+ too-many-arguments,
+ too-many-format-args,
+ too-many-return-statements,
+ too-many-statements,
+ line-too-long,
+ wrong-import-position,
+ wrong-import-order,
+ # -- END OF TEST-SPECIFIC SUPPRESSIONS --
+
+
+ # TODO(https://github.com/PyCQA/pylint/issues/59#issuecomment-283774279):
+ # Enable cyclic-import after a 1.7-or-later pylint release that
+ # recognizes our disable=cyclic-import suppressions.
+ cyclic-import,
+ # TODO(https://github.com/grpc/grpc/issues/8622): Enable this after the
+ # Beta API is removed.
+ duplicate-code,
+ # TODO(https://github.com/grpc/grpc/issues/261): Doesn't seem to
+ # understand enum and concurrent.futures; look into this later with the
+ # latest pylint version.
+ import-error,
+ # TODO(https://github.com/grpc/grpc/issues/261): Enable this one.
+ # Should take a little configuration but not much.
+ invalid-name,
+ # TODO(https://github.com/grpc/grpc/issues/261): This doesn't seem to
+ # work for now? Try with a later pylint?
+ locally-disabled,
+ # NOTE(nathaniel): What even is this? *Enabling* an inspection results
+ # in a warning? How does that encourage more analysis and coverage?
+ locally-enabled,
+ # NOTE(nathaniel): We don't write doc strings for most private code
+ # elements.
+ missing-docstring,
+ # NOTE(nathaniel): In numeric comparisons it is better to have the
+ # lesser (or lesser-or-equal-to) quantity on the left when the
+ # expression is true than it is to worry about which is an identifier
+ # and which a literal value.
+ misplaced-comparison-constant,
+ # NOTE(nathaniel): Our completely abstract interface classes don't have
+ # constructors.
+ no-init,
+ # TODO(https://github.com/grpc/grpc/issues/261): Doesn't yet play
+ # nicely with some of our code being implemented in Cython. Maybe in a
+ # later version?
+ no-name-in-module,
+ # TODO(https://github.com/grpc/grpc/issues/261): Suppress these where
+ # the odd shape of the authentication portion of the API forces them on
+ # us and enable everywhere else.
+ protected-access,
+ # NOTE(nathaniel): Pylint and I will probably never agree on this.
+ too-few-public-methods,
+ # NOTE(nathaniel): Pylint and I wil probably never agree on this for
+ # private classes. For public classes maybe?
+ too-many-instance-attributes,
+ # NOTE(nathaniel): Some of our modules have a lot of lines... of
+ # specification and documentation. Maybe if this were
+ # lines-of-code-based we would use it.
+ too-many-lines,
+ # TODO(https://github.com/grpc/grpc/issues/261): Maybe we could have
+ # this one if we extracted just a few more helper functions...
+ too-many-nested-blocks,
+ # NOTE(nathaniel): I have disputed the premise of this inspection from
+ # the beginning and will continue to do so until it goes away for good.
+ useless-else-on-loop,
diff --git a/BUILD b/BUILD
index 54215fe..c35a7d6 100644
--- a/BUILD
+++ b/BUILD
@@ -64,11 +64,11 @@
)
# This should be updated along with build.yaml
-g_stands_for = "gorgeous"
+g_stands_for = "gloriosa"
core_version = "6.0.0-dev"
-version = "1.11.0-dev"
+version = "1.13.0-dev"
GPR_PUBLIC_HDRS = [
"include/grpc/support/alloc.h",
@@ -141,7 +141,6 @@
"src/cpp/server/server_posix.cc",
"src/cpp/thread_manager/thread_manager.cc",
"src/cpp/util/byte_buffer_cc.cc",
- "src/cpp/util/slice_cc.cc",
"src/cpp/util/status.cc",
"src/cpp/util/string_ref.cc",
"src/cpp/util/time_cc.cc",
@@ -245,6 +244,8 @@
"include/grpcpp/support/byte_buffer.h",
"include/grpcpp/support/channel_arguments.h",
"include/grpcpp/support/config.h",
+ "include/grpcpp/support/proto_buffer_reader.h",
+ "include/grpcpp/support/proto_buffer_writer.h",
"include/grpcpp/support/slice.h",
"include/grpcpp/support/status.h",
"include/grpcpp/support/status_code_enum.h",
@@ -307,16 +308,8 @@
language = "c++",
deps = [
"grpc_base",
- "grpc_deadline_filter",
- "grpc_lb_policy_pick_first",
"grpc_http_filters",
- "grpc_max_age_filter",
- "grpc_message_size_filter",
- "grpc_resolver_dns_native",
- "grpc_resolver_sockaddr",
- "grpc_server_load_reporting",
"grpc_transport_chttp2_client_secure",
- "grpc_transport_chttp2_server_secure",
"grpc_transport_cronet_client_secure",
],
)
@@ -686,11 +679,11 @@
"src/core/lib/channel/channel_stack_builder.cc",
"src/core/lib/channel/channel_trace.cc",
"src/core/lib/channel/channel_trace_registry.cc",
- "src/core/lib/channel/status_util.cc",
"src/core/lib/channel/connected_channel.cc",
"src/core/lib/channel/handshaker.cc",
"src/core/lib/channel/handshaker_factory.cc",
"src/core/lib/channel/handshaker_registry.cc",
+ "src/core/lib/channel/status_util.cc",
"src/core/lib/compression/compression.cc",
"src/core/lib/compression/compression_internal.cc",
"src/core/lib/compression/message_compress.cc",
@@ -833,12 +826,12 @@
"src/core/lib/channel/channel_stack_builder.h",
"src/core/lib/channel/channel_trace.h",
"src/core/lib/channel/channel_trace_registry.h",
- "src/core/lib/channel/status_util.h",
"src/core/lib/channel/connected_channel.h",
"src/core/lib/channel/context.h",
"src/core/lib/channel/handshaker.h",
"src/core/lib/channel/handshaker_factory.h",
"src/core/lib/channel/handshaker_registry.h",
+ "src/core/lib/channel/status_util.h",
"src/core/lib/compression/algorithm_metadata.h",
"src/core/lib/compression/compression_internal.h",
"src/core/lib/compression/message_compress.h",
@@ -992,6 +985,7 @@
# standard plugins
"census",
"grpc_deadline_filter",
+ "grpc_client_authority_filter",
"grpc_lb_policy_pick_first",
"grpc_lb_policy_round_robin",
"grpc_server_load_reporting",
@@ -1060,6 +1054,7 @@
deps = [
"gpr_base",
"grpc_base",
+ "grpc_client_authority_filter",
"grpc_deadline_filter",
"inlined_vector",
"orphanable",
@@ -1097,6 +1092,20 @@
)
grpc_cc_library(
+ name = "grpc_client_authority_filter",
+ srcs = [
+ "src/core/ext/filters/http/client_authority_filter.cc",
+ ],
+ hdrs = [
+ "src/core/ext/filters/http/client_authority_filter.h",
+ ],
+ language = "c++",
+ deps = [
+ "grpc_base",
+ ],
+)
+
+grpc_cc_library(
name = "grpc_message_size_filter",
srcs = [
"src/core/ext/filters/message_size/message_size_filter.cc",
@@ -1174,6 +1183,7 @@
],
hdrs = [
"src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h",
+ "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h",
@@ -1202,6 +1212,7 @@
],
hdrs = [
"src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h",
+ "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h",
@@ -1221,9 +1232,6 @@
grpc_cc_library(
name = "grpc_lb_subchannel_list",
- srcs = [
- "src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc",
- ],
hdrs = [
"src/core/ext/filters/client_channel/lb_policy/subchannel_list.h",
],
@@ -1277,6 +1285,20 @@
)
grpc_cc_library(
+ name = "lb_load_data_store",
+ srcs = [
+ "src/cpp/server/load_reporter/load_data_store.cc",
+ ],
+ hdrs = [
+ "src/cpp/server/load_reporter/load_data_store.h",
+ ],
+ language = "c++",
+ deps = [
+ "grpc++",
+ ],
+)
+
+grpc_cc_library(
name = "grpc_resolver_dns_native",
srcs = [
"src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc",
@@ -1340,6 +1362,7 @@
srcs = [
"src/core/lib/http/httpcli_security_connector.cc",
"src/core/lib/security/context/security_context.cc",
+ "src/core/lib/security/credentials/alts/alts_credentials.cc",
"src/core/lib/security/credentials/composite/composite_credentials.cc",
"src/core/lib/security/credentials/credentials.cc",
"src/core/lib/security/credentials/credentials_metadata.cc",
@@ -1353,7 +1376,6 @@
"src/core/lib/security/credentials/oauth2/oauth2_credentials.cc",
"src/core/lib/security/credentials/plugin/plugin_credentials.cc",
"src/core/lib/security/credentials/ssl/ssl_credentials.cc",
- "src/core/lib/security/credentials/alts/alts_credentials.cc",
"src/core/lib/security/security_connector/alts_security_connector.cc",
"src/core/lib/security/security_connector/security_connector.cc",
"src/core/lib/security/transport/client_auth_filter.cc",
@@ -1366,7 +1388,9 @@
"src/core/lib/surface/init_secure.cc",
],
hdrs = [
+ "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h",
"src/core/lib/security/context/security_context.h",
+ "src/core/lib/security/credentials/alts/alts_credentials.h",
"src/core/lib/security/credentials/composite/composite_credentials.h",
"src/core/lib/security/credentials/credentials.h",
"src/core/lib/security/credentials/fake/fake_credentials.h",
@@ -1378,7 +1402,6 @@
"src/core/lib/security/credentials/oauth2/oauth2_credentials.h",
"src/core/lib/security/credentials/plugin/plugin_credentials.h",
"src/core/lib/security/credentials/ssl/ssl_credentials.h",
- "src/core/lib/security/credentials/alts/alts_credentials.h",
"src/core/lib/security/security_connector/alts_security_connector.h",
"src/core/lib/security/security_connector/security_connector.h",
"src/core/lib/security/transport/auth_filters.h",
@@ -1472,9 +1495,11 @@
grpc_cc_library(
name = "grpc_transport_chttp2_client_connector",
srcs = [
+ "src/core/ext/transport/chttp2/client/authority.cc",
"src/core/ext/transport/chttp2/client/chttp2_connector.cc",
],
hdrs = [
+ "src/core/ext/transport/chttp2/client/authority.h",
"src/core/ext/transport/chttp2/client/chttp2_connector.h",
],
language = "c++",
@@ -1600,11 +1625,9 @@
name = "tsi_interface",
srcs = [
"src/core/tsi/transport_security.cc",
- "src/core/tsi/transport_security_adapter.cc",
],
hdrs = [
"src/core/tsi/transport_security.h",
- "src/core/tsi/transport_security_adapter.h",
"src/core/tsi/transport_security_interface.h",
],
language = "c++",
@@ -1641,8 +1664,8 @@
"src/core/tsi/alts/frame_protector/frame_handler.h",
"src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.h",
"src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.h",
- "src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.h",
"src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol.h",
+ "src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.h",
"src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.h",
"src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.h",
"src/core/tsi/transport_security_grpc.h",
@@ -1697,25 +1720,26 @@
"src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.h",
"src/core/tsi/alts/handshaker/transport_security_common_api.h",
],
+ public_hdrs = GRPC_SECURE_PUBLIC_HDRS,
external_deps = [
"nanopb",
],
language = "c++",
deps = [
- "alts_proto",
- "gpr",
- "grpc_base",
+ "alts_proto",
+ "gpr",
+ "grpc_base",
],
)
grpc_cc_library(
name = "tsi",
srcs = [
- "src/core/tsi/alts_transport_security.cc",
"src/core/tsi/alts/handshaker/alts_handshaker_client.cc",
"src/core/tsi/alts/handshaker/alts_tsi_event.cc",
"src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc",
"src/core/tsi/alts/handshaker/alts_tsi_utils.cc",
+ "src/core/tsi/alts_transport_security.cc",
"src/core/tsi/fake_transport_security.cc",
"src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc",
"src/core/tsi/ssl/session_cache/ssl_session_cache.cc",
@@ -1724,12 +1748,12 @@
"src/core/tsi/transport_security_grpc.cc",
],
hdrs = [
- "src/core/tsi/alts_transport_security.h",
"src/core/tsi/alts/handshaker/alts_handshaker_client.h",
"src/core/tsi/alts/handshaker/alts_tsi_event.h",
"src/core/tsi/alts/handshaker/alts_tsi_handshaker.h",
"src/core/tsi/alts/handshaker/alts_tsi_handshaker_private.h",
"src/core/tsi/alts/handshaker/alts_tsi_utils.h",
+ "src/core/tsi/alts_transport_security.h",
"src/core/tsi/fake_transport_security.h",
"src/core/tsi/ssl/session_cache/ssl_session.h",
"src/core/tsi/ssl/session_cache/ssl_session_cache.h",
@@ -1861,6 +1885,8 @@
language = "c++",
public_hdrs = [
"include/grpc++/impl/codegen/proto_utils.h",
+ "include/grpcpp/impl/codegen/proto_buffer_reader.h",
+ "include/grpcpp/impl/codegen/proto_buffer_writer.h",
"include/grpcpp/impl/codegen/proto_utils.h",
],
deps = [
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 56dd61e..93f51e7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -24,7 +24,7 @@
cmake_minimum_required(VERSION 2.8)
set(PACKAGE_NAME "grpc")
-set(PACKAGE_VERSION "1.11.0-dev")
+set(PACKAGE_VERSION "1.13.0-dev")
set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
set(PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}")
set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/")
@@ -34,6 +34,7 @@
set(gRPC_INSTALL_LIBDIR "lib" CACHE STRING "Installation directory for libraries")
set(gRPC_INSTALL_INCLUDEDIR "include" CACHE STRING "Installation directory for headers")
set(gRPC_INSTALL_CMAKEDIR "lib/cmake/${PACKAGE_NAME}" CACHE STRING "Installation directory for cmake config files")
+set(gRPC_INSTALL_SHAREDIR "share/grpc" CACHE STRING "Installation directory for root certificates")
# Options
option(gRPC_BUILD_TESTS "Build tests" OFF)
@@ -289,7 +290,6 @@
add_dependencies(buildtests_c grpc_completion_queue_threading_test)
add_dependencies(buildtests_c grpc_credentials_test)
add_dependencies(buildtests_c grpc_fetch_oauth2)
-add_dependencies(buildtests_c grpc_invalid_channel_args_test)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_c grpc_json_token_test)
endif()
@@ -455,6 +455,7 @@
add_dependencies(buildtests_c h2_uds_nosec_test)
endif()
add_dependencies(buildtests_c inproc_nosec_test)
+add_dependencies(buildtests_c alts_credentials_fuzzer_one_entry)
add_dependencies(buildtests_c api_fuzzer_one_entry)
add_dependencies(buildtests_c client_fuzzer_one_entry)
add_dependencies(buildtests_c hpack_parser_fuzzer_test_one_entry)
@@ -585,6 +586,7 @@
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx json_run_localhost)
endif()
+add_dependencies(buildtests_cxx lb_load_data_store_test)
add_dependencies(buildtests_cxx memory_test)
add_dependencies(buildtests_cxx metrics_client)
add_dependencies(buildtests_cxx mock_test)
@@ -605,12 +607,16 @@
add_dependencies(buildtests_cxx reconnect_interop_server)
add_dependencies(buildtests_cxx ref_counted_ptr_test)
add_dependencies(buildtests_cxx ref_counted_test)
+add_dependencies(buildtests_cxx retry_throttle_test)
add_dependencies(buildtests_cxx secure_auth_context_test)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx secure_sync_unary_ping_pong_test)
endif()
add_dependencies(buildtests_cxx server_builder_plugin_test)
add_dependencies(buildtests_cxx server_builder_test)
+if(_gRPC_PLATFORM_POSIX)
+add_dependencies(buildtests_cxx server_builder_with_socket_mutator_test)
+endif()
add_dependencies(buildtests_cxx server_context_test_spouse_test)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx server_crash_test)
@@ -1145,9 +1151,9 @@
third_party/nanopb/pb_decode.c
third_party/nanopb/pb_encode.c
src/core/tsi/transport_security.cc
- src/core/tsi/transport_security_adapter.cc
src/core/ext/transport/chttp2/client/insecure/channel_create.cc
src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc
+ src/core/ext/transport/chttp2/client/authority.cc
src/core/ext/transport/chttp2/client/chttp2_connector.cc
src/core/ext/filters/client_channel/backup_poller.cc
src/core/ext/filters/client_channel/channel_connectivity.cc
@@ -1192,7 +1198,6 @@
src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c
src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc
src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
- src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc
src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc
@@ -1205,6 +1210,7 @@
src/core/ext/census/grpc_context.cc
src/core/ext/filters/max_age/max_age_filter.cc
src/core/ext/filters/message_size/message_size_filter.cc
+ src/core/ext/filters/http/client_authority_filter.cc
src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc
src/core/ext/filters/workarounds/workaround_utils.cc
src/core/plugin_registry/grpc_plugin_registry.cc
@@ -1449,36 +1455,6 @@
src/core/lib/transport/transport.cc
src/core/lib/transport/transport_op_string.cc
src/core/lib/debug/trace.cc
- src/core/ext/filters/deadline/deadline_filter.cc
- src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
- src/core/ext/filters/client_channel/backup_poller.cc
- src/core/ext/filters/client_channel/channel_connectivity.cc
- src/core/ext/filters/client_channel/client_channel.cc
- src/core/ext/filters/client_channel/client_channel_factory.cc
- src/core/ext/filters/client_channel/client_channel_plugin.cc
- src/core/ext/filters/client_channel/connector.cc
- src/core/ext/filters/client_channel/http_connect_handshaker.cc
- src/core/ext/filters/client_channel/http_proxy.cc
- src/core/ext/filters/client_channel/lb_policy.cc
- src/core/ext/filters/client_channel/lb_policy_factory.cc
- src/core/ext/filters/client_channel/lb_policy_registry.cc
- src/core/ext/filters/client_channel/method_params.cc
- src/core/ext/filters/client_channel/parse_address.cc
- src/core/ext/filters/client_channel/proxy_mapper.cc
- src/core/ext/filters/client_channel/proxy_mapper_registry.cc
- src/core/ext/filters/client_channel/resolver.cc
- src/core/ext/filters/client_channel/resolver_registry.cc
- src/core/ext/filters/client_channel/retry_throttle.cc
- src/core/ext/filters/client_channel/subchannel.cc
- src/core/ext/filters/client_channel/subchannel_index.cc
- src/core/ext/filters/client_channel/uri_parser.cc
- src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc
- src/core/ext/filters/max_age/max_age_filter.cc
- src/core/ext/filters/message_size/message_size_filter.cc
- src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc
- src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc
- src/core/ext/filters/load_reporting/server_load_reporting_filter.cc
- src/core/ext/filters/load_reporting/server_load_reporting_plugin.cc
src/core/ext/transport/cronet/client/secure/cronet_channel_create.cc
src/core/ext/transport/cronet/transport/cronet_api_dummy.cc
src/core/ext/transport/cronet/transport/cronet_transport.cc
@@ -1510,6 +1486,28 @@
src/core/ext/filters/http/http_filters_plugin.cc
src/core/ext/filters/http/message_compress/message_compress_filter.cc
src/core/ext/filters/http/server/http_server_filter.cc
+ src/core/ext/filters/client_channel/backup_poller.cc
+ src/core/ext/filters/client_channel/channel_connectivity.cc
+ src/core/ext/filters/client_channel/client_channel.cc
+ src/core/ext/filters/client_channel/client_channel_factory.cc
+ src/core/ext/filters/client_channel/client_channel_plugin.cc
+ src/core/ext/filters/client_channel/connector.cc
+ src/core/ext/filters/client_channel/http_connect_handshaker.cc
+ src/core/ext/filters/client_channel/http_proxy.cc
+ src/core/ext/filters/client_channel/lb_policy.cc
+ src/core/ext/filters/client_channel/lb_policy_factory.cc
+ src/core/ext/filters/client_channel/lb_policy_registry.cc
+ src/core/ext/filters/client_channel/method_params.cc
+ src/core/ext/filters/client_channel/parse_address.cc
+ src/core/ext/filters/client_channel/proxy_mapper.cc
+ src/core/ext/filters/client_channel/proxy_mapper_registry.cc
+ src/core/ext/filters/client_channel/resolver.cc
+ src/core/ext/filters/client_channel/resolver_registry.cc
+ src/core/ext/filters/client_channel/retry_throttle.cc
+ src/core/ext/filters/client_channel/subchannel.cc
+ src/core/ext/filters/client_channel/subchannel_index.cc
+ src/core/ext/filters/client_channel/uri_parser.cc
+ src/core/ext/filters/deadline/deadline_filter.cc
src/core/lib/http/httpcli_security_connector.cc
src/core/lib/security/context/security_context.cc
src/core/lib/security/credentials/alts/alts_credentials.cc
@@ -1571,9 +1569,9 @@
third_party/nanopb/pb_decode.c
third_party/nanopb/pb_encode.c
src/core/tsi/transport_security.cc
- src/core/tsi/transport_security_adapter.cc
src/core/ext/transport/chttp2/client/insecure/channel_create.cc
src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc
+ src/core/ext/transport/chttp2/client/authority.cc
src/core/ext/transport/chttp2/client/chttp2_connector.cc
src/core/tsi/alts_transport_security.cc
src/core/tsi/fake_transport_security.cc
@@ -1582,8 +1580,8 @@
src/core/tsi/ssl/session_cache/ssl_session_openssl.cc
src/core/tsi/ssl_transport_security.cc
src/core/tsi/transport_security_grpc.cc
- src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc
- src/core/ext/transport/chttp2/server/chttp2_server.cc
+ src/core/ext/filters/load_reporting/server_load_reporting_filter.cc
+ src/core/ext/filters/load_reporting/server_load_reporting_plugin.cc
src/core/plugin_registry/grpc_cronet_plugin_registry.cc
)
@@ -1643,20 +1641,9 @@
include/grpc/impl/codegen/sync_generic.h
include/grpc/impl/codegen/sync_posix.h
include/grpc/impl/codegen/sync_windows.h
- include/grpc/byte_buffer.h
- include/grpc/byte_buffer_reader.h
- include/grpc/compression.h
- include/grpc/fork.h
- include/grpc/grpc.h
- include/grpc/grpc_posix.h
- include/grpc/grpc_security_constants.h
- include/grpc/load_reporting.h
- include/grpc/slice.h
- include/grpc/slice_buffer.h
- include/grpc/status.h
- include/grpc/support/workaround_list.h
include/grpc/grpc_cronet.h
include/grpc/grpc_security.h
+ include/grpc/grpc_security_constants.h
)
string(REPLACE "include/" "" _path ${_hdr})
get_filename_component(_path ${_path} PATH)
@@ -1688,6 +1675,7 @@
test/core/end2end/fixtures/proxy.cc
test/core/iomgr/endpoint_tests.cc
test/core/util/debugger_macros.cc
+ test/core/util/fuzzer_util.cc
test/core/util/grpc_profiler.cc
test/core/util/histogram.cc
test/core/util/memory_counters.cc
@@ -1991,6 +1979,7 @@
test/core/end2end/fixtures/proxy.cc
test/core/iomgr/endpoint_tests.cc
test/core/util/debugger_macros.cc
+ test/core/util/fuzzer_util.cc
test/core/util/grpc_profiler.cc
test/core/util/histogram.cc
test/core/util/memory_counters.cc
@@ -2470,6 +2459,7 @@
src/core/ext/transport/chttp2/server/chttp2_server.cc
src/core/ext/transport/chttp2/client/insecure/channel_create.cc
src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc
+ src/core/ext/transport/chttp2/client/authority.cc
src/core/ext/transport/chttp2/client/chttp2_connector.cc
src/core/ext/filters/client_channel/backup_poller.cc
src/core/ext/filters/client_channel/channel_connectivity.cc
@@ -2514,11 +2504,11 @@
third_party/nanopb/pb_decode.c
third_party/nanopb/pb_encode.c
src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
- src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc
src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
src/core/ext/census/grpc_context.cc
src/core/ext/filters/max_age/max_age_filter.cc
src/core/ext/filters/message_size/message_size_filter.cc
+ src/core/ext/filters/http/client_authority_filter.cc
src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc
src/core/ext/filters/workarounds/workaround_utils.cc
src/core/plugin_registry/grpc_unsecure_plugin_registry.cc
@@ -2730,7 +2720,6 @@
src/cpp/server/server_posix.cc
src/cpp/thread_manager/thread_manager.cc
src/cpp/util/byte_buffer_cc.cc
- src/cpp/util/slice_cc.cc
src/cpp/util/status.cc
src/cpp/util/string_ref.cc
src/cpp/util/time_cc.cc
@@ -2855,6 +2844,8 @@
include/grpcpp/support/byte_buffer.h
include/grpcpp/support/channel_arguments.h
include/grpcpp/support/config.h
+ include/grpcpp/support/proto_buffer_reader.h
+ include/grpcpp/support/proto_buffer_writer.h
include/grpcpp/support/slice.h
include/grpcpp/support/status.h
include/grpcpp/support/status_code_enum.h
@@ -2973,6 +2964,8 @@
include/grpcpp/impl/codegen/sync_stream.h
include/grpcpp/impl/codegen/time.h
include/grpc++/impl/codegen/proto_utils.h
+ include/grpcpp/impl/codegen/proto_buffer_reader.h
+ include/grpcpp/impl/codegen/proto_buffer_writer.h
include/grpcpp/impl/codegen/proto_utils.h
include/grpc++/impl/codegen/config_protobuf.h
include/grpcpp/impl/codegen/config_protobuf.h
@@ -3081,13 +3074,13 @@
src/cpp/server/server_posix.cc
src/cpp/thread_manager/thread_manager.cc
src/cpp/util/byte_buffer_cc.cc
- src/cpp/util/slice_cc.cc
src/cpp/util/status.cc
src/cpp/util/string_ref.cc
src/cpp/util/time_cc.cc
src/cpp/codegen/codegen_init.cc
src/core/ext/transport/chttp2/client/insecure/channel_create.cc
src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc
+ src/core/ext/transport/chttp2/client/authority.cc
src/core/ext/transport/chttp2/client/chttp2_connector.cc
src/core/ext/transport/chttp2/transport/bin_decoder.cc
src/core/ext/transport/chttp2/transport/bin_encoder.cc
@@ -3415,6 +3408,8 @@
include/grpcpp/support/byte_buffer.h
include/grpcpp/support/channel_arguments.h
include/grpcpp/support/config.h
+ include/grpcpp/support/proto_buffer_reader.h
+ include/grpcpp/support/proto_buffer_writer.h
include/grpcpp/support/slice.h
include/grpcpp/support/status.h
include/grpcpp/support/status_code_enum.h
@@ -3958,6 +3953,8 @@
include/grpc/impl/codegen/sync_posix.h
include/grpc/impl/codegen/sync_windows.h
include/grpc++/impl/codegen/proto_utils.h
+ include/grpcpp/impl/codegen/proto_buffer_reader.h
+ include/grpcpp/impl/codegen/proto_buffer_writer.h
include/grpcpp/impl/codegen/proto_utils.h
include/grpc++/impl/codegen/config_protobuf.h
include/grpcpp/impl/codegen/config_protobuf.h
@@ -4131,6 +4128,8 @@
include/grpc/impl/codegen/sync_posix.h
include/grpc/impl/codegen/sync_windows.h
include/grpc++/impl/codegen/proto_utils.h
+ include/grpcpp/impl/codegen/proto_buffer_reader.h
+ include/grpcpp/impl/codegen/proto_buffer_writer.h
include/grpcpp/impl/codegen/proto_utils.h
include/grpc++/impl/codegen/config_protobuf.h
include/grpcpp/impl/codegen/config_protobuf.h
@@ -4179,7 +4178,6 @@
src/cpp/server/server_posix.cc
src/cpp/thread_manager/thread_manager.cc
src/cpp/util/byte_buffer_cc.cc
- src/cpp/util/slice_cc.cc
src/cpp/util/status.cc
src/cpp/util/string_ref.cc
src/cpp/util/time_cc.cc
@@ -4303,6 +4301,8 @@
include/grpcpp/support/byte_buffer.h
include/grpcpp/support/channel_arguments.h
include/grpcpp/support/config.h
+ include/grpcpp/support/proto_buffer_reader.h
+ include/grpcpp/support/proto_buffer_writer.h
include/grpcpp/support/slice.h
include/grpcpp/support/status.h
include/grpcpp/support/status_code_enum.h
@@ -4979,6 +4979,49 @@
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
+add_library(lb_load_data_store
+ src/cpp/server/load_reporter/load_data_store.cc
+)
+
+if(WIN32 AND MSVC)
+ set_target_properties(lb_load_data_store PROPERTIES COMPILE_PDB_NAME "lb_load_data_store"
+ COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
+ )
+ if (gRPC_INSTALL)
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/lb_load_data_store.pdb
+ DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL
+ )
+ endif()
+endif()
+
+
+target_include_directories(lb_load_data_store
+ PUBLIC $<INSTALL_INTERFACE:${gRPC_INSTALL_INCLUDEDIR}> $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
+ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+ PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
+ PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR}
+ PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR}
+ PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR}
+ PRIVATE ${_gRPC_CARES_INCLUDE_DIR}
+ PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
+ PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
+ PRIVATE third_party/googletest/googletest/include
+ PRIVATE third_party/googletest/googletest
+ PRIVATE third_party/googletest/googlemock/include
+ PRIVATE third_party/googletest/googlemock
+ PRIVATE ${_gRPC_PROTO_GENS_DIR}
+)
+
+target_link_libraries(lb_load_data_store
+ ${_gRPC_PROTOBUF_LIBRARIES}
+ ${_gRPC_ALLTARGETS_LIBRARIES}
+ grpc++
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
if (gRPC_BUILD_CODEGEN)
add_library(qps
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.pb.cc
@@ -4997,10 +5040,18 @@
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/control.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/control.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/control.grpc.pb.h
- ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/services.pb.cc
- ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/services.grpc.pb.cc
- ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/services.pb.h
- ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/services.grpc.pb.h
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/benchmark_service.pb.cc
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/benchmark_service.grpc.pb.cc
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/benchmark_service.pb.h
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/benchmark_service.grpc.pb.h
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/report_qps_scenario_service.pb.cc
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/report_qps_scenario_service.pb.h
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.h
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/worker_service.pb.cc
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/worker_service.grpc.pb.cc
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/worker_service.pb.h
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/worker_service.grpc.pb.h
test/cpp/qps/benchmark_config.cc
test/cpp/qps/client_async.cc
test/cpp/qps/client_sync.cc
@@ -5037,7 +5088,13 @@
src/proto/grpc/testing/control.proto
)
protobuf_generate_grpc_cpp(
- src/proto/grpc/testing/services.proto
+ src/proto/grpc/testing/benchmark_service.proto
+)
+protobuf_generate_grpc_cpp(
+ src/proto/grpc/testing/report_qps_scenario_service.proto
+)
+protobuf_generate_grpc_cpp(
+ src/proto/grpc/testing/worker_service.proto
)
target_include_directories(qps
@@ -5205,6 +5262,7 @@
test/core/end2end/tests/bad_ping.cc
test/core/end2end/tests/binary_metadata.cc
test/core/end2end/tests/call_creds.cc
+ test/core/end2end/tests/call_host_override.cc
test/core/end2end/tests/cancel_after_accept.cc
test/core/end2end/tests/cancel_after_client_done.cc
test/core/end2end/tests/cancel_after_invoke.cc
@@ -5251,6 +5309,7 @@
test/core/end2end/tests/retry_exceeds_buffer_size_in_initial_batch.cc
test/core/end2end/tests/retry_exceeds_buffer_size_in_subsequent_batch.cc
test/core/end2end/tests/retry_non_retriable_status.cc
+ test/core/end2end/tests/retry_non_retriable_status_before_recv_trailing_metadata_started.cc
test/core/end2end/tests/retry_recv_initial_metadata.cc
test/core/end2end/tests/retry_recv_message.cc
test/core/end2end/tests/retry_server_pushback_delay.cc
@@ -5321,6 +5380,7 @@
test/core/end2end/tests/bad_hostname.cc
test/core/end2end/tests/bad_ping.cc
test/core/end2end/tests/binary_metadata.cc
+ test/core/end2end/tests/call_host_override.cc
test/core/end2end/tests/cancel_after_accept.cc
test/core/end2end/tests/cancel_after_client_done.cc
test/core/end2end/tests/cancel_after_invoke.cc
@@ -5367,6 +5427,7 @@
test/core/end2end/tests/retry_exceeds_buffer_size_in_initial_batch.cc
test/core/end2end/tests/retry_exceeds_buffer_size_in_subsequent_batch.cc
test/core/end2end/tests/retry_non_retriable_status.cc
+ test/core/end2end/tests/retry_non_retriable_status_before_recv_trailing_metadata_started.cc
test/core/end2end/tests/retry_recv_initial_metadata.cc
test/core/end2end/tests/retry_recv_message.cc
test/core/end2end/tests/retry_server_pushback_delay.cc
@@ -5696,15 +5757,6 @@
gpr
)
-
-if (gRPC_INSTALL)
- install(TARGETS check_epollexclusive EXPORT gRPCTargets
- RUNTIME DESTINATION ${gRPC_INSTALL_BINDIR}
- LIBRARY DESTINATION ${gRPC_INSTALL_LIBDIR}
- ARCHIVE DESTINATION ${gRPC_INSTALL_LIBDIR}
- )
-endif()
-
if (gRPC_BUILD_TESTS)
add_executable(chttp2_hpack_encoder_test
@@ -6980,15 +7032,6 @@
gpr
)
-
-if (gRPC_INSTALL)
- install(TARGETS grpc_create_jwt EXPORT gRPCTargets
- RUNTIME DESTINATION ${gRPC_INSTALL_BINDIR}
- LIBRARY DESTINATION ${gRPC_INSTALL_LIBDIR}
- ARCHIVE DESTINATION ${gRPC_INSTALL_LIBDIR}
- )
-endif()
-
if (gRPC_BUILD_TESTS)
add_executable(grpc_credentials_test
@@ -7046,34 +7089,6 @@
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
-
-add_executable(grpc_invalid_channel_args_test
- test/core/surface/invalid_channel_args_test.cc
-)
-
-
-target_include_directories(grpc_invalid_channel_args_test
- PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
- PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
- PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
- PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR}
- PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR}
- PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR}
- PRIVATE ${_gRPC_CARES_INCLUDE_DIR}
- PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
- PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
-)
-
-target_link_libraries(grpc_invalid_channel_args_test
- ${_gRPC_ALLTARGETS_LIBRARIES}
- grpc_test_util
- grpc
- gpr_test_util
- gpr
-)
-
-endif (gRPC_BUILD_TESTS)
-if (gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_executable(grpc_json_token_test
@@ -7156,15 +7171,6 @@
gpr
)
-
-if (gRPC_INSTALL)
- install(TARGETS grpc_print_google_default_creds_token EXPORT gRPCTargets
- RUNTIME DESTINATION ${gRPC_INSTALL_BINDIR}
- LIBRARY DESTINATION ${gRPC_INSTALL_LIBDIR}
- ARCHIVE DESTINATION ${gRPC_INSTALL_LIBDIR}
- )
-endif()
-
if (gRPC_BUILD_TESTS)
add_executable(grpc_security_connector_test
@@ -7246,15 +7252,6 @@
gpr
)
-
-if (gRPC_INSTALL)
- install(TARGETS grpc_verify_jwt EXPORT gRPCTargets
- RUNTIME DESTINATION ${gRPC_INSTALL_BINDIR}
- LIBRARY DESTINATION ${gRPC_INSTALL_LIBDIR}
- ARCHIVE DESTINATION ${gRPC_INSTALL_LIBDIR}
- )
-endif()
-
if (gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX)
@@ -9752,6 +9749,7 @@
grpc_unsecure
gpr_test_util
gpr
+ grpc++_test_config
${_gRPC_GFLAGS_LIBRARIES}
)
@@ -9795,6 +9793,7 @@
grpc_unsecure
gpr_test_util
gpr
+ grpc++_test_config
${_gRPC_GFLAGS_LIBRARIES}
)
@@ -9838,6 +9837,7 @@
grpc_unsecure
gpr_test_util
gpr
+ grpc++_test_config
${_gRPC_GFLAGS_LIBRARIES}
)
@@ -9881,6 +9881,7 @@
grpc_unsecure
gpr_test_util
gpr
+ grpc++_test_config
${_gRPC_GFLAGS_LIBRARIES}
)
@@ -9924,6 +9925,7 @@
grpc_unsecure
gpr_test_util
gpr
+ grpc++_test_config
${_gRPC_GFLAGS_LIBRARIES}
)
@@ -9967,6 +9969,7 @@
grpc_unsecure
gpr_test_util
gpr
+ grpc++_test_config
${_gRPC_GFLAGS_LIBRARIES}
)
@@ -10010,6 +10013,7 @@
grpc_unsecure
gpr_test_util
gpr
+ grpc++_test_config
${_gRPC_GFLAGS_LIBRARIES}
)
@@ -10053,6 +10057,7 @@
grpc_unsecure
gpr_test_util
gpr
+ grpc++_test_config
${_gRPC_GFLAGS_LIBRARIES}
)
@@ -10096,6 +10101,7 @@
grpc_unsecure
gpr_test_util
gpr
+ grpc++_test_config
${_gRPC_GFLAGS_LIBRARIES}
)
@@ -10139,6 +10145,7 @@
grpc_unsecure
gpr_test_util
gpr
+ grpc++_test_config
${_gRPC_GFLAGS_LIBRARIES}
)
@@ -10226,6 +10233,7 @@
grpc_unsecure
gpr_test_util
gpr
+ grpc++_test_config
${_gRPC_GFLAGS_LIBRARIES}
)
@@ -10269,6 +10277,7 @@
grpc_unsecure
gpr_test_util
gpr
+ grpc++_test_config
${_gRPC_GFLAGS_LIBRARIES}
)
@@ -10312,6 +10321,7 @@
grpc_unsecure
gpr_test_util
gpr
+ grpc++_test_config
${_gRPC_GFLAGS_LIBRARIES}
)
@@ -10799,10 +10809,18 @@
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/payloads.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/payloads.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/payloads.grpc.pb.h
- ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/services.pb.cc
- ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/services.grpc.pb.cc
- ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/services.pb.h
- ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/services.grpc.pb.h
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/benchmark_service.pb.cc
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/benchmark_service.grpc.pb.cc
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/benchmark_service.pb.h
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/benchmark_service.grpc.pb.h
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/report_qps_scenario_service.pb.cc
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/report_qps_scenario_service.pb.h
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.h
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/worker_service.pb.cc
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/worker_service.grpc.pb.cc
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/worker_service.pb.h
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/worker_service.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/stats.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/stats.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/stats.pb.h
@@ -10822,7 +10840,13 @@
src/proto/grpc/testing/payloads.proto
)
protobuf_generate_grpc_cpp(
- src/proto/grpc/testing/services.proto
+ src/proto/grpc/testing/benchmark_service.proto
+)
+protobuf_generate_grpc_cpp(
+ src/proto/grpc/testing/report_qps_scenario_service.proto
+)
+protobuf_generate_grpc_cpp(
+ src/proto/grpc/testing/worker_service.proto
)
protobuf_generate_grpc_cpp(
src/proto/grpc/testing/stats.proto
@@ -10871,10 +10895,18 @@
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/payloads.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/payloads.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/payloads.grpc.pb.h
- ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/services.pb.cc
- ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/services.grpc.pb.cc
- ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/services.pb.h
- ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/services.grpc.pb.h
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/benchmark_service.pb.cc
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/benchmark_service.grpc.pb.cc
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/benchmark_service.pb.h
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/benchmark_service.grpc.pb.h
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/report_qps_scenario_service.pb.cc
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/report_qps_scenario_service.pb.h
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.h
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/worker_service.pb.cc
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/worker_service.grpc.pb.cc
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/worker_service.pb.h
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/worker_service.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/stats.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/stats.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/stats.pb.h
@@ -10895,7 +10927,13 @@
src/proto/grpc/testing/payloads.proto
)
protobuf_generate_grpc_cpp(
- src/proto/grpc/testing/services.proto
+ src/proto/grpc/testing/benchmark_service.proto
+)
+protobuf_generate_grpc_cpp(
+ src/proto/grpc/testing/report_qps_scenario_service.proto
+)
+protobuf_generate_grpc_cpp(
+ src/proto/grpc/testing/worker_service.proto
)
protobuf_generate_grpc_cpp(
src/proto/grpc/testing/stats.proto
@@ -12280,6 +12318,46 @@
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
+add_executable(lb_load_data_store_test
+ test/cpp/server/load_reporter/load_data_store_test.cc
+ third_party/googletest/googletest/src/gtest-all.cc
+ third_party/googletest/googlemock/src/gmock-all.cc
+)
+
+
+target_include_directories(lb_load_data_store_test
+ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+ PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
+ PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR}
+ PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR}
+ PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR}
+ PRIVATE ${_gRPC_CARES_INCLUDE_DIR}
+ PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
+ PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
+ PRIVATE third_party/googletest/googletest/include
+ PRIVATE third_party/googletest/googletest
+ PRIVATE third_party/googletest/googlemock/include
+ PRIVATE third_party/googletest/googlemock
+ PRIVATE ${_gRPC_PROTO_GENS_DIR}
+)
+
+target_link_libraries(lb_load_data_store_test
+ ${_gRPC_PROTOBUF_LIBRARIES}
+ ${_gRPC_ALLTARGETS_LIBRARIES}
+ lb_load_data_store
+ grpc++_test_util
+ grpc_test_util
+ grpc++
+ grpc
+ gpr_test_util
+ gpr
+ ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
add_executable(memory_test
test/core/gprpp/memory_test.cc
third_party/googletest/googletest/src/gtest-all.cc
@@ -12959,6 +13037,43 @@
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
+add_executable(retry_throttle_test
+ test/core/client_channel/retry_throttle_test.cc
+ third_party/googletest/googletest/src/gtest-all.cc
+ third_party/googletest/googlemock/src/gmock-all.cc
+)
+
+
+target_include_directories(retry_throttle_test
+ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+ PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
+ PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR}
+ PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR}
+ PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR}
+ PRIVATE ${_gRPC_CARES_INCLUDE_DIR}
+ PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
+ PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
+ PRIVATE third_party/googletest/googletest/include
+ PRIVATE third_party/googletest/googletest
+ PRIVATE third_party/googletest/googlemock/include
+ PRIVATE third_party/googletest/googlemock
+ PRIVATE ${_gRPC_PROTO_GENS_DIR}
+)
+
+target_link_libraries(retry_throttle_test
+ ${_gRPC_PROTOBUF_LIBRARIES}
+ ${_gRPC_ALLTARGETS_LIBRARIES}
+ grpc_test_util
+ grpc
+ gpr_test_util
+ gpr
+ ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
add_executable(secure_auth_context_test
test/cpp/common/secure_auth_context_test.cc
third_party/googletest/googletest/src/gtest-all.cc
@@ -13133,6 +13248,61 @@
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
+if(_gRPC_PLATFORM_POSIX)
+
+add_executable(server_builder_with_socket_mutator_test
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h
+ test/cpp/server/server_builder_with_socket_mutator_test.cc
+ third_party/googletest/googletest/src/gtest-all.cc
+ third_party/googletest/googlemock/src/gmock-all.cc
+)
+
+protobuf_generate_grpc_cpp(
+ src/proto/grpc/testing/echo_messages.proto
+)
+protobuf_generate_grpc_cpp(
+ src/proto/grpc/testing/echo.proto
+)
+
+target_include_directories(server_builder_with_socket_mutator_test
+ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+ PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
+ PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR}
+ PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR}
+ PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR}
+ PRIVATE ${_gRPC_CARES_INCLUDE_DIR}
+ PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
+ PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
+ PRIVATE third_party/googletest/googletest/include
+ PRIVATE third_party/googletest/googletest
+ PRIVATE third_party/googletest/googlemock/include
+ PRIVATE third_party/googletest/googlemock
+ PRIVATE ${_gRPC_PROTO_GENS_DIR}
+)
+
+target_link_libraries(server_builder_with_socket_mutator_test
+ ${_gRPC_PROTOBUF_LIBRARIES}
+ ${_gRPC_ALLTARGETS_LIBRARIES}
+ grpc++_test_util_unsecure
+ grpc_test_util_unsecure
+ gpr_test_util
+ grpc++_unsecure
+ grpc_unsecure
+ gpr
+ ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif()
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
add_executable(server_context_test_spouse_test
test/cpp/test/server_context_test_spouse_test.cc
@@ -13916,15 +14086,6 @@
)
-if (gRPC_INSTALL)
- install(TARGETS gen_hpack_tables EXPORT gRPCTargets
- RUNTIME DESTINATION ${gRPC_INSTALL_BINDIR}
- LIBRARY DESTINATION ${gRPC_INSTALL_LIBDIR}
- ARCHIVE DESTINATION ${gRPC_INSTALL_LIBDIR}
- )
-endif()
-
-
add_executable(gen_legal_metadata_characters
tools/codegen/core/gen_legal_metadata_characters.cc
)
@@ -13947,15 +14108,6 @@
)
-if (gRPC_INSTALL)
- install(TARGETS gen_legal_metadata_characters EXPORT gRPCTargets
- RUNTIME DESTINATION ${gRPC_INSTALL_BINDIR}
- LIBRARY DESTINATION ${gRPC_INSTALL_LIBDIR}
- ARCHIVE DESTINATION ${gRPC_INSTALL_LIBDIR}
- )
-endif()
-
-
add_executable(gen_percent_encoding_tables
tools/codegen/core/gen_percent_encoding_tables.cc
)
@@ -13977,15 +14129,6 @@
${_gRPC_ALLTARGETS_LIBRARIES}
)
-
-if (gRPC_INSTALL)
- install(TARGETS gen_percent_encoding_tables EXPORT gRPCTargets
- RUNTIME DESTINATION ${gRPC_INSTALL_BINDIR}
- LIBRARY DESTINATION ${gRPC_INSTALL_LIBDIR}
- ARCHIVE DESTINATION ${gRPC_INSTALL_LIBDIR}
- )
-endif()
-
if (gRPC_BUILD_TESTS)
add_executable(badreq_bad_client_test
@@ -15629,6 +15772,35 @@
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
+add_executable(alts_credentials_fuzzer_one_entry
+ test/core/security/alts_credentials_fuzzer.cc
+ test/core/util/one_corpus_entry_fuzzer.cc
+)
+
+
+target_include_directories(alts_credentials_fuzzer_one_entry
+ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+ PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
+ PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR}
+ PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR}
+ PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR}
+ PRIVATE ${_gRPC_CARES_INCLUDE_DIR}
+ PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
+ PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
+)
+
+target_link_libraries(alts_credentials_fuzzer_one_entry
+ ${_gRPC_ALLTARGETS_LIBRARIES}
+ grpc_test_util
+ grpc
+ gpr_test_util
+ gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
add_executable(api_fuzzer_one_entry
test/core/end2end/fuzzers/api_fuzzer.cc
test/core/util/one_corpus_entry_fuzzer.cc
@@ -16025,3 +16197,6 @@
DESTINATION ${gRPC_INSTALL_CMAKEDIR}
)
endforeach()
+
+install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/etc/roots.pem
+ DESTINATION ${gRPC_INSTALL_SHAREDIR})
diff --git a/INSTALL.md b/INSTALL.md
index 40faf97..59e127f 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -142,7 +142,7 @@
> call "%VS140COMNTOOLS%..\..\VC\vcvarsall.bat" x64
> cmake .. -GNinja -DCMAKE_BUILD_TYPE=Release
> cmake --build .
-> ninja
+> ninja install
```
### msys2 (with mingw)
diff --git a/Makefile b/Makefile
index a6275aa..ba765f0 100644
--- a/Makefile
+++ b/Makefile
@@ -421,8 +421,8 @@
endif
CORE_VERSION = 6.0.0-dev
-CPP_VERSION = 1.11.0-dev
-CSHARP_VERSION = 1.11.0-dev
+CPP_VERSION = 1.13.0-dev
+CSHARP_VERSION = 1.13.0-dev
CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES))
CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS)
@@ -503,7 +503,7 @@
OPENSSL_ALPN_CHECK_CMD = $(PKG_CONFIG) --atleast-version=1.0.2 openssl
OPENSSL_NPN_CHECK_CMD = $(PKG_CONFIG) --atleast-version=1.0.1 openssl
ZLIB_CHECK_CMD = $(PKG_CONFIG) --exists zlib
-PROTOBUF_CHECK_CMD = $(PKG_CONFIG) --atleast-version=3.0.0 protobuf
+PROTOBUF_CHECK_CMD = $(PKG_CONFIG) --atleast-version=3.5.0 protobuf
CARES_CHECK_CMD = $(PKG_CONFIG) --atleast-version=1.11.0 libcares
else # HAS_PKG_CONFIG
@@ -919,7 +919,7 @@
@echo
@echo "DEPENDENCY ERROR"
@echo
- @echo "The target you are trying to run requires protobuf 3.0.0+"
+ @echo "The target you are trying to run requires protobuf 3.5.0+"
@echo "Your system doesn't have it, and neither does the third_party directory."
@echo
@echo "Please consult INSTALL to get more information."
@@ -933,7 +933,7 @@
@echo
@echo "DEPENDENCY ERROR"
@echo
- @echo "The target you are trying to run requires protobuf-compiler 3.0.0+"
+ @echo "The target you are trying to run requires protobuf-compiler 3.5.0+"
@echo "Your system doesn't have it, and neither does the third_party directory."
@echo
@echo "Please consult INSTALL to get more information."
@@ -960,6 +960,7 @@
algorithm_test: $(BINDIR)/$(CONFIG)/algorithm_test
alloc_test: $(BINDIR)/$(CONFIG)/alloc_test
alpn_test: $(BINDIR)/$(CONFIG)/alpn_test
+alts_credentials_fuzzer: $(BINDIR)/$(CONFIG)/alts_credentials_fuzzer
api_fuzzer: $(BINDIR)/$(CONFIG)/api_fuzzer
arena_test: $(BINDIR)/$(CONFIG)/arena_test
avl_test: $(BINDIR)/$(CONFIG)/avl_test
@@ -1017,7 +1018,6 @@
grpc_create_jwt: $(BINDIR)/$(CONFIG)/grpc_create_jwt
grpc_credentials_test: $(BINDIR)/$(CONFIG)/grpc_credentials_test
grpc_fetch_oauth2: $(BINDIR)/$(CONFIG)/grpc_fetch_oauth2
-grpc_invalid_channel_args_test: $(BINDIR)/$(CONFIG)/grpc_invalid_channel_args_test
grpc_json_token_test: $(BINDIR)/$(CONFIG)/grpc_json_token_test
grpc_jwt_verifier_test: $(BINDIR)/$(CONFIG)/grpc_jwt_verifier_test
grpc_print_google_default_creds_token: $(BINDIR)/$(CONFIG)/grpc_print_google_default_creds_token
@@ -1179,6 +1179,7 @@
interop_server: $(BINDIR)/$(CONFIG)/interop_server
interop_test: $(BINDIR)/$(CONFIG)/interop_test
json_run_localhost: $(BINDIR)/$(CONFIG)/json_run_localhost
+lb_load_data_store_test: $(BINDIR)/$(CONFIG)/lb_load_data_store_test
memory_test: $(BINDIR)/$(CONFIG)/memory_test
metrics_client: $(BINDIR)/$(CONFIG)/metrics_client
mock_test: $(BINDIR)/$(CONFIG)/mock_test
@@ -1195,10 +1196,12 @@
reconnect_interop_server: $(BINDIR)/$(CONFIG)/reconnect_interop_server
ref_counted_ptr_test: $(BINDIR)/$(CONFIG)/ref_counted_ptr_test
ref_counted_test: $(BINDIR)/$(CONFIG)/ref_counted_test
+retry_throttle_test: $(BINDIR)/$(CONFIG)/retry_throttle_test
secure_auth_context_test: $(BINDIR)/$(CONFIG)/secure_auth_context_test
secure_sync_unary_ping_pong_test: $(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test
server_builder_plugin_test: $(BINDIR)/$(CONFIG)/server_builder_plugin_test
server_builder_test: $(BINDIR)/$(CONFIG)/server_builder_test
+server_builder_with_socket_mutator_test: $(BINDIR)/$(CONFIG)/server_builder_with_socket_mutator_test
server_context_test_spouse_test: $(BINDIR)/$(CONFIG)/server_context_test_spouse_test
server_crash_test: $(BINDIR)/$(CONFIG)/server_crash_test
server_crash_test_client: $(BINDIR)/$(CONFIG)/server_crash_test_client
@@ -1324,6 +1327,7 @@
resolver_component_tests_runner_invoker: $(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker
address_sorting_test_unsecure: $(BINDIR)/$(CONFIG)/address_sorting_test_unsecure
address_sorting_test: $(BINDIR)/$(CONFIG)/address_sorting_test
+alts_credentials_fuzzer_one_entry: $(BINDIR)/$(CONFIG)/alts_credentials_fuzzer_one_entry
api_fuzzer_one_entry: $(BINDIR)/$(CONFIG)/api_fuzzer_one_entry
client_fuzzer_one_entry: $(BINDIR)/$(CONFIG)/client_fuzzer_one_entry
hpack_parser_fuzzer_test_one_entry: $(BINDIR)/$(CONFIG)/hpack_parser_fuzzer_test_one_entry
@@ -1390,9 +1394,9 @@
pc_cxx_unsecure: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc++_unsecure.pc
ifeq ($(EMBED_OPENSSL),true)
-privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libhttp2_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl_crypto_test_data_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_buf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_chacha_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_compiler_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_constant_time_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_spake25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_dsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ecdh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_scrypt_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_p256-x86_64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ctrdrbg_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_hkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_lhash_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_obj_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs7_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pool_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_refcount_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_file_test_gtest_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_gtest_main_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_thread_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_tab_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_v3name_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_span_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a $(LIBDIR)/$(CONFIG)/libbenchmark.a
+privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libhttp2_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/liblb_load_data_store.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl_crypto_test_data_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_buf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_chacha_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_compiler_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_constant_time_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_spake25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_dsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ecdh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_scrypt_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_p256-x86_64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ctrdrbg_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_hkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_lhash_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_obj_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs7_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pool_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_refcount_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_file_test_gtest_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_gtest_main_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_thread_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_tab_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_v3name_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_span_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a $(LIBDIR)/$(CONFIG)/libbenchmark.a
else
-privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libhttp2_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libbenchmark.a
+privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libhttp2_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/liblb_load_data_store.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libbenchmark.a
endif
@@ -1455,7 +1459,6 @@
$(BINDIR)/$(CONFIG)/grpc_completion_queue_threading_test \
$(BINDIR)/$(CONFIG)/grpc_credentials_test \
$(BINDIR)/$(CONFIG)/grpc_fetch_oauth2 \
- $(BINDIR)/$(CONFIG)/grpc_invalid_channel_args_test \
$(BINDIR)/$(CONFIG)/grpc_json_token_test \
$(BINDIR)/$(CONFIG)/grpc_jwt_verifier_test \
$(BINDIR)/$(CONFIG)/grpc_security_connector_test \
@@ -1571,6 +1574,7 @@
$(BINDIR)/$(CONFIG)/h2_sockpair_1byte_nosec_test \
$(BINDIR)/$(CONFIG)/h2_uds_nosec_test \
$(BINDIR)/$(CONFIG)/inproc_nosec_test \
+ $(BINDIR)/$(CONFIG)/alts_credentials_fuzzer_one_entry \
$(BINDIR)/$(CONFIG)/api_fuzzer_one_entry \
$(BINDIR)/$(CONFIG)/client_fuzzer_one_entry \
$(BINDIR)/$(CONFIG)/hpack_parser_fuzzer_test_one_entry \
@@ -1661,6 +1665,7 @@
$(BINDIR)/$(CONFIG)/interop_server \
$(BINDIR)/$(CONFIG)/interop_test \
$(BINDIR)/$(CONFIG)/json_run_localhost \
+ $(BINDIR)/$(CONFIG)/lb_load_data_store_test \
$(BINDIR)/$(CONFIG)/memory_test \
$(BINDIR)/$(CONFIG)/metrics_client \
$(BINDIR)/$(CONFIG)/mock_test \
@@ -1677,10 +1682,12 @@
$(BINDIR)/$(CONFIG)/reconnect_interop_server \
$(BINDIR)/$(CONFIG)/ref_counted_ptr_test \
$(BINDIR)/$(CONFIG)/ref_counted_test \
+ $(BINDIR)/$(CONFIG)/retry_throttle_test \
$(BINDIR)/$(CONFIG)/secure_auth_context_test \
$(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test \
$(BINDIR)/$(CONFIG)/server_builder_plugin_test \
$(BINDIR)/$(CONFIG)/server_builder_test \
+ $(BINDIR)/$(CONFIG)/server_builder_with_socket_mutator_test \
$(BINDIR)/$(CONFIG)/server_context_test_spouse_test \
$(BINDIR)/$(CONFIG)/server_crash_test \
$(BINDIR)/$(CONFIG)/server_crash_test_client \
@@ -1831,6 +1838,7 @@
$(BINDIR)/$(CONFIG)/interop_server \
$(BINDIR)/$(CONFIG)/interop_test \
$(BINDIR)/$(CONFIG)/json_run_localhost \
+ $(BINDIR)/$(CONFIG)/lb_load_data_store_test \
$(BINDIR)/$(CONFIG)/memory_test \
$(BINDIR)/$(CONFIG)/metrics_client \
$(BINDIR)/$(CONFIG)/mock_test \
@@ -1847,10 +1855,12 @@
$(BINDIR)/$(CONFIG)/reconnect_interop_server \
$(BINDIR)/$(CONFIG)/ref_counted_ptr_test \
$(BINDIR)/$(CONFIG)/ref_counted_test \
+ $(BINDIR)/$(CONFIG)/retry_throttle_test \
$(BINDIR)/$(CONFIG)/secure_auth_context_test \
$(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test \
$(BINDIR)/$(CONFIG)/server_builder_plugin_test \
$(BINDIR)/$(CONFIG)/server_builder_test \
+ $(BINDIR)/$(CONFIG)/server_builder_with_socket_mutator_test \
$(BINDIR)/$(CONFIG)/server_context_test_spouse_test \
$(BINDIR)/$(CONFIG)/server_crash_test \
$(BINDIR)/$(CONFIG)/server_crash_test_client \
@@ -1990,8 +2000,6 @@
$(Q) $(BINDIR)/$(CONFIG)/grpc_completion_queue_threading_test || ( echo test grpc_completion_queue_threading_test failed ; exit 1 )
$(E) "[RUN] Testing grpc_credentials_test"
$(Q) $(BINDIR)/$(CONFIG)/grpc_credentials_test || ( echo test grpc_credentials_test failed ; exit 1 )
- $(E) "[RUN] Testing grpc_invalid_channel_args_test"
- $(Q) $(BINDIR)/$(CONFIG)/grpc_invalid_channel_args_test || ( echo test grpc_invalid_channel_args_test failed ; exit 1 )
$(E) "[RUN] Testing grpc_json_token_test"
$(Q) $(BINDIR)/$(CONFIG)/grpc_json_token_test || ( echo test grpc_json_token_test failed ; exit 1 )
$(E) "[RUN] Testing grpc_jwt_verifier_test"
@@ -2284,6 +2292,8 @@
$(Q) $(BINDIR)/$(CONFIG)/inproc_sync_unary_ping_pong_test || ( echo test inproc_sync_unary_ping_pong_test failed ; exit 1 )
$(E) "[RUN] Testing interop_test"
$(Q) $(BINDIR)/$(CONFIG)/interop_test || ( echo test interop_test failed ; exit 1 )
+ $(E) "[RUN] Testing lb_load_data_store_test"
+ $(Q) $(BINDIR)/$(CONFIG)/lb_load_data_store_test || ( echo test lb_load_data_store_test failed ; exit 1 )
$(E) "[RUN] Testing memory_test"
$(Q) $(BINDIR)/$(CONFIG)/memory_test || ( echo test memory_test failed ; exit 1 )
$(E) "[RUN] Testing mock_test"
@@ -2304,6 +2314,8 @@
$(Q) $(BINDIR)/$(CONFIG)/ref_counted_ptr_test || ( echo test ref_counted_ptr_test failed ; exit 1 )
$(E) "[RUN] Testing ref_counted_test"
$(Q) $(BINDIR)/$(CONFIG)/ref_counted_test || ( echo test ref_counted_test failed ; exit 1 )
+ $(E) "[RUN] Testing retry_throttle_test"
+ $(Q) $(BINDIR)/$(CONFIG)/retry_throttle_test || ( echo test retry_throttle_test failed ; exit 1 )
$(E) "[RUN] Testing secure_auth_context_test"
$(Q) $(BINDIR)/$(CONFIG)/secure_auth_context_test || ( echo test secure_auth_context_test failed ; exit 1 )
$(E) "[RUN] Testing secure_sync_unary_ping_pong_test"
@@ -2312,6 +2324,8 @@
$(Q) $(BINDIR)/$(CONFIG)/server_builder_plugin_test || ( echo test server_builder_plugin_test failed ; exit 1 )
$(E) "[RUN] Testing server_builder_test"
$(Q) $(BINDIR)/$(CONFIG)/server_builder_test || ( echo test server_builder_test failed ; exit 1 )
+ $(E) "[RUN] Testing server_builder_with_socket_mutator_test"
+ $(Q) $(BINDIR)/$(CONFIG)/server_builder_with_socket_mutator_test || ( echo test server_builder_with_socket_mutator_test failed ; exit 1 )
$(E) "[RUN] Testing server_context_test_spouse_test"
$(Q) $(BINDIR)/$(CONFIG)/server_context_test_spouse_test || ( echo test server_context_test_spouse_test failed ; exit 1 )
$(E) "[RUN] Testing server_crash_test"
@@ -2569,6 +2583,22 @@
endif
ifeq ($(NO_PROTOC),true)
+$(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc: protoc_dep_error
+$(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc: protoc_dep_error
+else
+
+$(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc: src/proto/grpc/testing/benchmark_service.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/messages.pb.cc
+ $(E) "[PROTOC] Generating protobuf CC file from $<"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
+
+$(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc: src/proto/grpc/testing/benchmark_service.proto $(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc
+ $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
+endif
+
+ifeq ($(NO_PROTOC),true)
$(GENDIR)/src/proto/grpc/testing/compiler_test.pb.cc: protoc_dep_error
$(GENDIR)/src/proto/grpc/testing/compiler_test.grpc.pb.cc: protoc_dep_error
else
@@ -2715,16 +2745,16 @@
endif
ifeq ($(NO_PROTOC),true)
-$(GENDIR)/src/proto/grpc/testing/services.pb.cc: protoc_dep_error
-$(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc: protoc_dep_error
+$(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc: protoc_dep_error
+$(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc: protoc_dep_error
else
-$(GENDIR)/src/proto/grpc/testing/services.pb.cc: src/proto/grpc/testing/services.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc
+$(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc: src/proto/grpc/testing/report_qps_scenario_service.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/control.pb.cc
$(E) "[PROTOC] Generating protobuf CC file from $<"
$(Q) mkdir -p `dirname $@`
$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
-$(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc: src/proto/grpc/testing/services.proto $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc
+$(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc: src/proto/grpc/testing/report_qps_scenario_service.proto $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc
$(E) "[GRPC] Generating gRPC's protobuf service CC file from $<"
$(Q) mkdir -p `dirname $@`
$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
@@ -2762,6 +2792,22 @@
$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
endif
+ifeq ($(NO_PROTOC),true)
+$(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc: protoc_dep_error
+$(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc: protoc_dep_error
+else
+
+$(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc: src/proto/grpc/testing/worker_service.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/control.pb.cc
+ $(E) "[PROTOC] Generating protobuf CC file from $<"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
+
+$(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc: src/proto/grpc/testing/worker_service.proto $(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc
+ $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
+endif
+
ifeq ($(CONFIG),stapprof)
src/core/profiling/stap_timers.c: $(GENDIR)/src/core/profiling/stap_probes.h
@@ -3494,9 +3540,9 @@
third_party/nanopb/pb_decode.c \
third_party/nanopb/pb_encode.c \
src/core/tsi/transport_security.cc \
- src/core/tsi/transport_security_adapter.cc \
src/core/ext/transport/chttp2/client/insecure/channel_create.cc \
src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc \
+ src/core/ext/transport/chttp2/client/authority.cc \
src/core/ext/transport/chttp2/client/chttp2_connector.cc \
src/core/ext/filters/client_channel/backup_poller.cc \
src/core/ext/filters/client_channel/channel_connectivity.cc \
@@ -3541,7 +3587,6 @@
src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \
src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc \
src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc \
- src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc \
src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc \
@@ -3554,6 +3599,7 @@
src/core/ext/census/grpc_context.cc \
src/core/ext/filters/max_age/max_age_filter.cc \
src/core/ext/filters/message_size/message_size_filter.cc \
+ src/core/ext/filters/http/client_authority_filter.cc \
src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc \
src/core/ext/filters/workarounds/workaround_utils.cc \
src/core/plugin_registry/grpc_plugin_registry.cc \
@@ -3798,36 +3844,6 @@
src/core/lib/transport/transport.cc \
src/core/lib/transport/transport_op_string.cc \
src/core/lib/debug/trace.cc \
- src/core/ext/filters/deadline/deadline_filter.cc \
- src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc \
- src/core/ext/filters/client_channel/backup_poller.cc \
- src/core/ext/filters/client_channel/channel_connectivity.cc \
- src/core/ext/filters/client_channel/client_channel.cc \
- src/core/ext/filters/client_channel/client_channel_factory.cc \
- src/core/ext/filters/client_channel/client_channel_plugin.cc \
- src/core/ext/filters/client_channel/connector.cc \
- src/core/ext/filters/client_channel/http_connect_handshaker.cc \
- src/core/ext/filters/client_channel/http_proxy.cc \
- src/core/ext/filters/client_channel/lb_policy.cc \
- src/core/ext/filters/client_channel/lb_policy_factory.cc \
- src/core/ext/filters/client_channel/lb_policy_registry.cc \
- src/core/ext/filters/client_channel/method_params.cc \
- src/core/ext/filters/client_channel/parse_address.cc \
- src/core/ext/filters/client_channel/proxy_mapper.cc \
- src/core/ext/filters/client_channel/proxy_mapper_registry.cc \
- src/core/ext/filters/client_channel/resolver.cc \
- src/core/ext/filters/client_channel/resolver_registry.cc \
- src/core/ext/filters/client_channel/retry_throttle.cc \
- src/core/ext/filters/client_channel/subchannel.cc \
- src/core/ext/filters/client_channel/subchannel_index.cc \
- src/core/ext/filters/client_channel/uri_parser.cc \
- src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc \
- src/core/ext/filters/max_age/max_age_filter.cc \
- src/core/ext/filters/message_size/message_size_filter.cc \
- src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \
- src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc \
- src/core/ext/filters/load_reporting/server_load_reporting_filter.cc \
- src/core/ext/filters/load_reporting/server_load_reporting_plugin.cc \
src/core/ext/transport/cronet/client/secure/cronet_channel_create.cc \
src/core/ext/transport/cronet/transport/cronet_api_dummy.cc \
src/core/ext/transport/cronet/transport/cronet_transport.cc \
@@ -3859,6 +3875,28 @@
src/core/ext/filters/http/http_filters_plugin.cc \
src/core/ext/filters/http/message_compress/message_compress_filter.cc \
src/core/ext/filters/http/server/http_server_filter.cc \
+ src/core/ext/filters/client_channel/backup_poller.cc \
+ src/core/ext/filters/client_channel/channel_connectivity.cc \
+ src/core/ext/filters/client_channel/client_channel.cc \
+ src/core/ext/filters/client_channel/client_channel_factory.cc \
+ src/core/ext/filters/client_channel/client_channel_plugin.cc \
+ src/core/ext/filters/client_channel/connector.cc \
+ src/core/ext/filters/client_channel/http_connect_handshaker.cc \
+ src/core/ext/filters/client_channel/http_proxy.cc \
+ src/core/ext/filters/client_channel/lb_policy.cc \
+ src/core/ext/filters/client_channel/lb_policy_factory.cc \
+ src/core/ext/filters/client_channel/lb_policy_registry.cc \
+ src/core/ext/filters/client_channel/method_params.cc \
+ src/core/ext/filters/client_channel/parse_address.cc \
+ src/core/ext/filters/client_channel/proxy_mapper.cc \
+ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \
+ src/core/ext/filters/client_channel/resolver.cc \
+ src/core/ext/filters/client_channel/resolver_registry.cc \
+ src/core/ext/filters/client_channel/retry_throttle.cc \
+ src/core/ext/filters/client_channel/subchannel.cc \
+ src/core/ext/filters/client_channel/subchannel_index.cc \
+ src/core/ext/filters/client_channel/uri_parser.cc \
+ src/core/ext/filters/deadline/deadline_filter.cc \
src/core/lib/http/httpcli_security_connector.cc \
src/core/lib/security/context/security_context.cc \
src/core/lib/security/credentials/alts/alts_credentials.cc \
@@ -3920,9 +3958,9 @@
third_party/nanopb/pb_decode.c \
third_party/nanopb/pb_encode.c \
src/core/tsi/transport_security.cc \
- src/core/tsi/transport_security_adapter.cc \
src/core/ext/transport/chttp2/client/insecure/channel_create.cc \
src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc \
+ src/core/ext/transport/chttp2/client/authority.cc \
src/core/ext/transport/chttp2/client/chttp2_connector.cc \
src/core/tsi/alts_transport_security.cc \
src/core/tsi/fake_transport_security.cc \
@@ -3931,8 +3969,8 @@
src/core/tsi/ssl/session_cache/ssl_session_openssl.cc \
src/core/tsi/ssl_transport_security.cc \
src/core/tsi/transport_security_grpc.cc \
- src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc \
- src/core/ext/transport/chttp2/server/chttp2_server.cc \
+ src/core/ext/filters/load_reporting/server_load_reporting_filter.cc \
+ src/core/ext/filters/load_reporting/server_load_reporting_plugin.cc \
src/core/plugin_registry/grpc_cronet_plugin_registry.cc \
PUBLIC_HEADERS_C += \
@@ -3957,20 +3995,9 @@
include/grpc/impl/codegen/sync_generic.h \
include/grpc/impl/codegen/sync_posix.h \
include/grpc/impl/codegen/sync_windows.h \
- include/grpc/byte_buffer.h \
- include/grpc/byte_buffer_reader.h \
- include/grpc/compression.h \
- include/grpc/fork.h \
- include/grpc/grpc.h \
- include/grpc/grpc_posix.h \
- include/grpc/grpc_security_constants.h \
- include/grpc/load_reporting.h \
- include/grpc/slice.h \
- include/grpc/slice_buffer.h \
- include/grpc/status.h \
- include/grpc/support/workaround_list.h \
include/grpc/grpc_cronet.h \
include/grpc/grpc_security.h \
+ include/grpc/grpc_security_constants.h \
LIBGRPC_CRONET_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_CRONET_SRC))))
@@ -4036,6 +4063,7 @@
test/core/end2end/fixtures/proxy.cc \
test/core/iomgr/endpoint_tests.cc \
test/core/util/debugger_macros.cc \
+ test/core/util/fuzzer_util.cc \
test/core/util/grpc_profiler.cc \
test/core/util/histogram.cc \
test/core/util/memory_counters.cc \
@@ -4331,6 +4359,7 @@
test/core/end2end/fixtures/proxy.cc \
test/core/iomgr/endpoint_tests.cc \
test/core/util/debugger_macros.cc \
+ test/core/util/fuzzer_util.cc \
test/core/util/grpc_profiler.cc \
test/core/util/histogram.cc \
test/core/util/memory_counters.cc \
@@ -4789,6 +4818,7 @@
src/core/ext/transport/chttp2/server/chttp2_server.cc \
src/core/ext/transport/chttp2/client/insecure/channel_create.cc \
src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc \
+ src/core/ext/transport/chttp2/client/authority.cc \
src/core/ext/transport/chttp2/client/chttp2_connector.cc \
src/core/ext/filters/client_channel/backup_poller.cc \
src/core/ext/filters/client_channel/channel_connectivity.cc \
@@ -4833,11 +4863,11 @@
third_party/nanopb/pb_decode.c \
third_party/nanopb/pb_encode.c \
src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc \
- src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc \
src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc \
src/core/ext/census/grpc_context.cc \
src/core/ext/filters/max_age/max_age_filter.cc \
src/core/ext/filters/message_size/message_size_filter.cc \
+ src/core/ext/filters/http/client_authority_filter.cc \
src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc \
src/core/ext/filters/workarounds/workaround_utils.cc \
src/core/plugin_registry/grpc_unsecure_plugin_registry.cc \
@@ -5032,7 +5062,6 @@
src/cpp/server/server_posix.cc \
src/cpp/thread_manager/thread_manager.cc \
src/cpp/util/byte_buffer_cc.cc \
- src/cpp/util/slice_cc.cc \
src/cpp/util/status.cc \
src/cpp/util/string_ref.cc \
src/cpp/util/time_cc.cc \
@@ -5122,6 +5151,8 @@
include/grpcpp/support/byte_buffer.h \
include/grpcpp/support/channel_arguments.h \
include/grpcpp/support/config.h \
+ include/grpcpp/support/proto_buffer_reader.h \
+ include/grpcpp/support/proto_buffer_writer.h \
include/grpcpp/support/slice.h \
include/grpcpp/support/status.h \
include/grpcpp/support/status_code_enum.h \
@@ -5240,6 +5271,8 @@
include/grpcpp/impl/codegen/sync_stream.h \
include/grpcpp/impl/codegen/time.h \
include/grpc++/impl/codegen/proto_utils.h \
+ include/grpcpp/impl/codegen/proto_buffer_reader.h \
+ include/grpcpp/impl/codegen/proto_buffer_writer.h \
include/grpcpp/impl/codegen/proto_utils.h \
include/grpc++/impl/codegen/config_protobuf.h \
include/grpcpp/impl/codegen/config_protobuf.h \
@@ -5393,13 +5426,13 @@
src/cpp/server/server_posix.cc \
src/cpp/thread_manager/thread_manager.cc \
src/cpp/util/byte_buffer_cc.cc \
- src/cpp/util/slice_cc.cc \
src/cpp/util/status.cc \
src/cpp/util/string_ref.cc \
src/cpp/util/time_cc.cc \
src/cpp/codegen/codegen_init.cc \
src/core/ext/transport/chttp2/client/insecure/channel_create.cc \
src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc \
+ src/core/ext/transport/chttp2/client/authority.cc \
src/core/ext/transport/chttp2/client/chttp2_connector.cc \
src/core/ext/transport/chttp2/transport/bin_decoder.cc \
src/core/ext/transport/chttp2/transport/bin_encoder.cc \
@@ -5691,6 +5724,8 @@
include/grpcpp/support/byte_buffer.h \
include/grpcpp/support/channel_arguments.h \
include/grpcpp/support/config.h \
+ include/grpcpp/support/proto_buffer_reader.h \
+ include/grpcpp/support/proto_buffer_writer.h \
include/grpcpp/support/slice.h \
include/grpcpp/support/status.h \
include/grpcpp/support/status_code_enum.h \
@@ -6219,6 +6254,8 @@
include/grpc/impl/codegen/sync_posix.h \
include/grpc/impl/codegen/sync_windows.h \
include/grpc++/impl/codegen/proto_utils.h \
+ include/grpcpp/impl/codegen/proto_buffer_reader.h \
+ include/grpcpp/impl/codegen/proto_buffer_writer.h \
include/grpcpp/impl/codegen/proto_utils.h \
include/grpc++/impl/codegen/config_protobuf.h \
include/grpcpp/impl/codegen/config_protobuf.h \
@@ -6369,6 +6406,8 @@
include/grpc/impl/codegen/sync_posix.h \
include/grpc/impl/codegen/sync_windows.h \
include/grpc++/impl/codegen/proto_utils.h \
+ include/grpcpp/impl/codegen/proto_buffer_reader.h \
+ include/grpcpp/impl/codegen/proto_buffer_writer.h \
include/grpcpp/impl/codegen/proto_utils.h \
include/grpc++/impl/codegen/config_protobuf.h \
include/grpcpp/impl/codegen/config_protobuf.h \
@@ -6456,7 +6495,6 @@
src/cpp/server/server_posix.cc \
src/cpp/thread_manager/thread_manager.cc \
src/cpp/util/byte_buffer_cc.cc \
- src/cpp/util/slice_cc.cc \
src/cpp/util/status.cc \
src/cpp/util/string_ref.cc \
src/cpp/util/time_cc.cc \
@@ -6546,6 +6584,8 @@
include/grpcpp/support/byte_buffer.h \
include/grpcpp/support/channel_arguments.h \
include/grpcpp/support/config.h \
+ include/grpcpp/support/proto_buffer_reader.h \
+ include/grpcpp/support/proto_buffer_writer.h \
include/grpcpp/support/slice.h \
include/grpcpp/support/status.h \
include/grpcpp/support/status_code_enum.h \
@@ -7178,12 +7218,63 @@
endif
+LIBLB_LOAD_DATA_STORE_SRC = \
+ src/cpp/server/load_reporter/load_data_store.cc \
+
+PUBLIC_HEADERS_CXX += \
+
+LIBLB_LOAD_DATA_STORE_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBLB_LOAD_DATA_STORE_SRC))))
+
+
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure libraries if you don't have OpenSSL.
+
+$(LIBDIR)/$(CONFIG)/liblb_load_data_store.a: openssl_dep_error
+
+
+else
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay.
+
+$(LIBDIR)/$(CONFIG)/liblb_load_data_store.a: protobuf_dep_error
+
+
+else
+
+$(LIBDIR)/$(CONFIG)/liblb_load_data_store.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBLB_LOAD_DATA_STORE_OBJS)
+ $(E) "[AR] Creating $@"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) rm -f $(LIBDIR)/$(CONFIG)/liblb_load_data_store.a
+ $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/liblb_load_data_store.a $(LIBLB_LOAD_DATA_STORE_OBJS)
+ifeq ($(SYSTEM),Darwin)
+ $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/liblb_load_data_store.a
+endif
+
+
+
+
+endif
+
+endif
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(LIBLB_LOAD_DATA_STORE_OBJS:.o=.dep)
+endif
+endif
+
+
LIBQPS_SRC = \
$(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc \
$(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc \
$(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc \
$(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc \
- $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc \
+ $(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc \
+ $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc \
+ $(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc \
test/cpp/qps/benchmark_config.cc \
test/cpp/qps/client_async.cc \
test/cpp/qps/client_sync.cc \
@@ -7239,16 +7330,16 @@
-include $(LIBQPS_OBJS:.o=.dep)
endif
endif
-$(OBJDIR)/$(CONFIG)/test/cpp/qps/benchmark_config.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/qps/client_async.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/qps/client_sync.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/qps/driver.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/qps/parse_json.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/qps/qps_worker.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/qps/report.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/qps/server_async.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/qps/server_sync.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/qps/usage_timer.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/benchmark_config.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/client_async.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/client_sync.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/driver.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/parse_json.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/qps_worker.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/report.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/server_async.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/server_sync.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/usage_timer.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc
LIBGRPC_CSHARP_EXT_SRC = \
@@ -9832,6 +9923,7 @@
test/core/end2end/tests/bad_ping.cc \
test/core/end2end/tests/binary_metadata.cc \
test/core/end2end/tests/call_creds.cc \
+ test/core/end2end/tests/call_host_override.cc \
test/core/end2end/tests/cancel_after_accept.cc \
test/core/end2end/tests/cancel_after_client_done.cc \
test/core/end2end/tests/cancel_after_invoke.cc \
@@ -9878,6 +9970,7 @@
test/core/end2end/tests/retry_exceeds_buffer_size_in_initial_batch.cc \
test/core/end2end/tests/retry_exceeds_buffer_size_in_subsequent_batch.cc \
test/core/end2end/tests/retry_non_retriable_status.cc \
+ test/core/end2end/tests/retry_non_retriable_status_before_recv_trailing_metadata_started.cc \
test/core/end2end/tests/retry_recv_initial_metadata.cc \
test/core/end2end/tests/retry_recv_message.cc \
test/core/end2end/tests/retry_server_pushback_delay.cc \
@@ -9946,6 +10039,7 @@
test/core/end2end/tests/bad_hostname.cc \
test/core/end2end/tests/bad_ping.cc \
test/core/end2end/tests/binary_metadata.cc \
+ test/core/end2end/tests/call_host_override.cc \
test/core/end2end/tests/cancel_after_accept.cc \
test/core/end2end/tests/cancel_after_client_done.cc \
test/core/end2end/tests/cancel_after_invoke.cc \
@@ -9992,6 +10086,7 @@
test/core/end2end/tests/retry_exceeds_buffer_size_in_initial_batch.cc \
test/core/end2end/tests/retry_exceeds_buffer_size_in_subsequent_batch.cc \
test/core/end2end/tests/retry_non_retriable_status.cc \
+ test/core/end2end/tests/retry_non_retriable_status_before_recv_trailing_metadata_started.cc \
test/core/end2end/tests/retry_recv_initial_metadata.cc \
test/core/end2end/tests/retry_recv_message.cc \
test/core/end2end/tests/retry_server_pushback_delay.cc \
@@ -10139,6 +10234,38 @@
endif
+ALTS_CREDENTIALS_FUZZER_SRC = \
+ test/core/security/alts_credentials_fuzzer.cc \
+
+ALTS_CREDENTIALS_FUZZER_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(ALTS_CREDENTIALS_FUZZER_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/alts_credentials_fuzzer: openssl_dep_error
+
+else
+
+
+
+$(BINDIR)/$(CONFIG)/alts_credentials_fuzzer: $(ALTS_CREDENTIALS_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+ $(E) "[LD] Linking $@"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(LDXX) $(LDFLAGS) $(ALTS_CREDENTIALS_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/alts_credentials_fuzzer
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/security/alts_credentials_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_alts_credentials_fuzzer: $(ALTS_CREDENTIALS_FUZZER_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(ALTS_CREDENTIALS_FUZZER_OBJS:.o=.dep)
+endif
+endif
+
+
API_FUZZER_SRC = \
test/core/end2end/fuzzers/api_fuzzer.cc \
@@ -11969,38 +12096,6 @@
endif
-GRPC_INVALID_CHANNEL_ARGS_TEST_SRC = \
- test/core/surface/invalid_channel_args_test.cc \
-
-GRPC_INVALID_CHANNEL_ARGS_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPC_INVALID_CHANNEL_ARGS_TEST_SRC))))
-ifeq ($(NO_SECURE),true)
-
-# You can't build secure targets if you don't have OpenSSL.
-
-$(BINDIR)/$(CONFIG)/grpc_invalid_channel_args_test: openssl_dep_error
-
-else
-
-
-
-$(BINDIR)/$(CONFIG)/grpc_invalid_channel_args_test: $(GRPC_INVALID_CHANNEL_ARGS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
- $(E) "[LD] Linking $@"
- $(Q) mkdir -p `dirname $@`
- $(Q) $(LD) $(LDFLAGS) $(GRPC_INVALID_CHANNEL_ARGS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_invalid_channel_args_test
-
-endif
-
-$(OBJDIR)/$(CONFIG)/test/core/surface/invalid_channel_args_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
-
-deps_grpc_invalid_channel_args_test: $(GRPC_INVALID_CHANNEL_ARGS_TEST_OBJS:.o=.dep)
-
-ifneq ($(NO_SECURE),true)
-ifneq ($(NO_DEPS),true)
--include $(GRPC_INVALID_CHANNEL_ARGS_TEST_OBJS:.o=.dep)
-endif
-endif
-
-
GRPC_JSON_TOKEN_TEST_SRC = \
test/core/security/json_token_test.cc \
@@ -14625,7 +14720,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/alarm_test: protobuf_dep_error
@@ -14668,7 +14763,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/alts_counter_test: protobuf_dep_error
@@ -14711,7 +14806,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/alts_crypt_test: protobuf_dep_error
@@ -14754,7 +14849,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/alts_crypter_test: protobuf_dep_error
@@ -14797,7 +14892,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/alts_frame_handler_test: protobuf_dep_error
@@ -14841,7 +14936,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/alts_frame_protector_test: protobuf_dep_error
@@ -14886,7 +14981,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/alts_grpc_record_protocol_test: protobuf_dep_error
@@ -14929,7 +15024,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/alts_handshaker_client_test: protobuf_dep_error
@@ -14972,7 +15067,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/alts_handshaker_service_api_test: protobuf_dep_error
@@ -15015,7 +15110,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/alts_iovec_record_protocol_test: protobuf_dep_error
@@ -15058,7 +15153,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/alts_security_connector_test: protobuf_dep_error
@@ -15101,7 +15196,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/alts_tsi_handshaker_test: protobuf_dep_error
@@ -15144,7 +15239,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/alts_tsi_utils_test: protobuf_dep_error
@@ -15187,7 +15282,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/alts_zero_copy_grpc_protector_test: protobuf_dep_error
@@ -15230,7 +15325,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/async_end2end_test: protobuf_dep_error
@@ -15273,7 +15368,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/auth_property_iterator_test: protobuf_dep_error
@@ -15316,7 +15411,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/backoff_test: protobuf_dep_error
@@ -15359,7 +15454,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/bdp_estimator_test: protobuf_dep_error
@@ -15402,23 +15497,23 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/bm_arena: protobuf_dep_error
else
-$(BINDIR)/$(CONFIG)/bm_arena: $(PROTOBUF_DEP) $(BM_ARENA_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/bm_arena: $(PROTOBUF_DEP) $(BM_ARENA_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
- $(Q) $(LDXX) $(LDFLAGS) $(BM_ARENA_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_arena
+ $(Q) $(LDXX) $(LDFLAGS) $(BM_ARENA_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_arena
endif
endif
$(BM_ARENA_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX
-$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_arena.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_arena.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
deps_bm_arena: $(BM_ARENA_OBJS:.o=.dep)
@@ -15446,23 +15541,23 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/bm_call_create: protobuf_dep_error
else
-$(BINDIR)/$(CONFIG)/bm_call_create: $(PROTOBUF_DEP) $(BM_CALL_CREATE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/bm_call_create: $(PROTOBUF_DEP) $(BM_CALL_CREATE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
- $(Q) $(LDXX) $(LDFLAGS) $(BM_CALL_CREATE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_call_create
+ $(Q) $(LDXX) $(LDFLAGS) $(BM_CALL_CREATE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_call_create
endif
endif
$(BM_CALL_CREATE_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX
-$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_call_create.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_call_create.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
deps_bm_call_create: $(BM_CALL_CREATE_OBJS:.o=.dep)
@@ -15490,23 +15585,23 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/bm_chttp2_hpack: protobuf_dep_error
else
-$(BINDIR)/$(CONFIG)/bm_chttp2_hpack: $(PROTOBUF_DEP) $(BM_CHTTP2_HPACK_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/bm_chttp2_hpack: $(PROTOBUF_DEP) $(BM_CHTTP2_HPACK_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
- $(Q) $(LDXX) $(LDFLAGS) $(BM_CHTTP2_HPACK_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_chttp2_hpack
+ $(Q) $(LDXX) $(LDFLAGS) $(BM_CHTTP2_HPACK_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_chttp2_hpack
endif
endif
$(BM_CHTTP2_HPACK_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX
-$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_chttp2_hpack.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_chttp2_hpack.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
deps_bm_chttp2_hpack: $(BM_CHTTP2_HPACK_OBJS:.o=.dep)
@@ -15534,23 +15629,23 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/bm_chttp2_transport: protobuf_dep_error
else
-$(BINDIR)/$(CONFIG)/bm_chttp2_transport: $(PROTOBUF_DEP) $(BM_CHTTP2_TRANSPORT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/bm_chttp2_transport: $(PROTOBUF_DEP) $(BM_CHTTP2_TRANSPORT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
- $(Q) $(LDXX) $(LDFLAGS) $(BM_CHTTP2_TRANSPORT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_chttp2_transport
+ $(Q) $(LDXX) $(LDFLAGS) $(BM_CHTTP2_TRANSPORT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_chttp2_transport
endif
endif
$(BM_CHTTP2_TRANSPORT_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX
-$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_chttp2_transport.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_chttp2_transport.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
deps_bm_chttp2_transport: $(BM_CHTTP2_TRANSPORT_OBJS:.o=.dep)
@@ -15578,23 +15673,23 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/bm_closure: protobuf_dep_error
else
-$(BINDIR)/$(CONFIG)/bm_closure: $(PROTOBUF_DEP) $(BM_CLOSURE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/bm_closure: $(PROTOBUF_DEP) $(BM_CLOSURE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
- $(Q) $(LDXX) $(LDFLAGS) $(BM_CLOSURE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_closure
+ $(Q) $(LDXX) $(LDFLAGS) $(BM_CLOSURE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_closure
endif
endif
$(BM_CLOSURE_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX
-$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_closure.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_closure.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
deps_bm_closure: $(BM_CLOSURE_OBJS:.o=.dep)
@@ -15622,23 +15717,23 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/bm_cq: protobuf_dep_error
else
-$(BINDIR)/$(CONFIG)/bm_cq: $(PROTOBUF_DEP) $(BM_CQ_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/bm_cq: $(PROTOBUF_DEP) $(BM_CQ_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
- $(Q) $(LDXX) $(LDFLAGS) $(BM_CQ_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_cq
+ $(Q) $(LDXX) $(LDFLAGS) $(BM_CQ_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_cq
endif
endif
$(BM_CQ_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX
-$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_cq.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_cq.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
deps_bm_cq: $(BM_CQ_OBJS:.o=.dep)
@@ -15666,23 +15761,23 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/bm_cq_multiple_threads: protobuf_dep_error
else
-$(BINDIR)/$(CONFIG)/bm_cq_multiple_threads: $(PROTOBUF_DEP) $(BM_CQ_MULTIPLE_THREADS_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/bm_cq_multiple_threads: $(PROTOBUF_DEP) $(BM_CQ_MULTIPLE_THREADS_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
- $(Q) $(LDXX) $(LDFLAGS) $(BM_CQ_MULTIPLE_THREADS_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_cq_multiple_threads
+ $(Q) $(LDXX) $(LDFLAGS) $(BM_CQ_MULTIPLE_THREADS_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_cq_multiple_threads
endif
endif
$(BM_CQ_MULTIPLE_THREADS_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX
-$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_cq_multiple_threads.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_cq_multiple_threads.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
deps_bm_cq_multiple_threads: $(BM_CQ_MULTIPLE_THREADS_OBJS:.o=.dep)
@@ -15710,23 +15805,23 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/bm_error: protobuf_dep_error
else
-$(BINDIR)/$(CONFIG)/bm_error: $(PROTOBUF_DEP) $(BM_ERROR_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/bm_error: $(PROTOBUF_DEP) $(BM_ERROR_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
- $(Q) $(LDXX) $(LDFLAGS) $(BM_ERROR_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_error
+ $(Q) $(LDXX) $(LDFLAGS) $(BM_ERROR_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_error
endif
endif
$(BM_ERROR_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX
-$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_error.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_error.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
deps_bm_error: $(BM_ERROR_OBJS:.o=.dep)
@@ -15754,23 +15849,23 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/bm_fullstack_streaming_ping_pong: protobuf_dep_error
else
-$(BINDIR)/$(CONFIG)/bm_fullstack_streaming_ping_pong: $(PROTOBUF_DEP) $(BM_FULLSTACK_STREAMING_PING_PONG_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/bm_fullstack_streaming_ping_pong: $(PROTOBUF_DEP) $(BM_FULLSTACK_STREAMING_PING_PONG_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
- $(Q) $(LDXX) $(LDFLAGS) $(BM_FULLSTACK_STREAMING_PING_PONG_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_fullstack_streaming_ping_pong
+ $(Q) $(LDXX) $(LDFLAGS) $(BM_FULLSTACK_STREAMING_PING_PONG_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_fullstack_streaming_ping_pong
endif
endif
$(BM_FULLSTACK_STREAMING_PING_PONG_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX
-$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
deps_bm_fullstack_streaming_ping_pong: $(BM_FULLSTACK_STREAMING_PING_PONG_OBJS:.o=.dep)
@@ -15798,23 +15893,23 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/bm_fullstack_streaming_pump: protobuf_dep_error
else
-$(BINDIR)/$(CONFIG)/bm_fullstack_streaming_pump: $(PROTOBUF_DEP) $(BM_FULLSTACK_STREAMING_PUMP_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/bm_fullstack_streaming_pump: $(PROTOBUF_DEP) $(BM_FULLSTACK_STREAMING_PUMP_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
- $(Q) $(LDXX) $(LDFLAGS) $(BM_FULLSTACK_STREAMING_PUMP_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_fullstack_streaming_pump
+ $(Q) $(LDXX) $(LDFLAGS) $(BM_FULLSTACK_STREAMING_PUMP_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_fullstack_streaming_pump
endif
endif
$(BM_FULLSTACK_STREAMING_PUMP_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX
-$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_fullstack_streaming_pump.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_fullstack_streaming_pump.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
deps_bm_fullstack_streaming_pump: $(BM_FULLSTACK_STREAMING_PUMP_OBJS:.o=.dep)
@@ -15842,7 +15937,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/bm_fullstack_trickle: protobuf_dep_error
@@ -15886,23 +15981,23 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong: protobuf_dep_error
else
-$(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong: $(PROTOBUF_DEP) $(BM_FULLSTACK_UNARY_PING_PONG_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong: $(PROTOBUF_DEP) $(BM_FULLSTACK_UNARY_PING_PONG_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
- $(Q) $(LDXX) $(LDFLAGS) $(BM_FULLSTACK_UNARY_PING_PONG_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong
+ $(Q) $(LDXX) $(LDFLAGS) $(BM_FULLSTACK_UNARY_PING_PONG_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong
endif
endif
$(BM_FULLSTACK_UNARY_PING_PONG_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX
-$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
deps_bm_fullstack_unary_ping_pong: $(BM_FULLSTACK_UNARY_PING_PONG_OBJS:.o=.dep)
@@ -15930,23 +16025,23 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/bm_metadata: protobuf_dep_error
else
-$(BINDIR)/$(CONFIG)/bm_metadata: $(PROTOBUF_DEP) $(BM_METADATA_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/bm_metadata: $(PROTOBUF_DEP) $(BM_METADATA_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
- $(Q) $(LDXX) $(LDFLAGS) $(BM_METADATA_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_metadata
+ $(Q) $(LDXX) $(LDFLAGS) $(BM_METADATA_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_metadata
endif
endif
$(BM_METADATA_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX
-$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_metadata.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_metadata.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
deps_bm_metadata: $(BM_METADATA_OBJS:.o=.dep)
@@ -15974,23 +16069,23 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/bm_pollset: protobuf_dep_error
else
-$(BINDIR)/$(CONFIG)/bm_pollset: $(PROTOBUF_DEP) $(BM_POLLSET_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/bm_pollset: $(PROTOBUF_DEP) $(BM_POLLSET_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
- $(Q) $(LDXX) $(LDFLAGS) $(BM_POLLSET_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_pollset
+ $(Q) $(LDXX) $(LDFLAGS) $(BM_POLLSET_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_pollset
endif
endif
$(BM_POLLSET_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX
-$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_pollset.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_pollset.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
deps_bm_pollset: $(BM_POLLSET_OBJS:.o=.dep)
@@ -16018,7 +16113,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/byte_stream_test: protobuf_dep_error
@@ -16061,7 +16156,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/channel_arguments_test: protobuf_dep_error
@@ -16104,7 +16199,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/channel_filter_test: protobuf_dep_error
@@ -16148,7 +16243,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/channel_trace_test: protobuf_dep_error
@@ -16194,7 +16289,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/check_gcp_environment_linux_test: protobuf_dep_error
@@ -16237,7 +16332,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/check_gcp_environment_windows_test: protobuf_dep_error
@@ -16280,7 +16375,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/chttp2_settings_timeout_test: protobuf_dep_error
@@ -16323,7 +16418,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/cli_call_test: protobuf_dep_error
@@ -16367,7 +16462,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/client_channel_stress_test: protobuf_dep_error
@@ -16413,7 +16508,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/client_crash_test: protobuf_dep_error
@@ -16456,7 +16551,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/client_crash_test_server: protobuf_dep_error
@@ -16499,7 +16594,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/client_lb_end2end_test: protobuf_dep_error
@@ -16529,7 +16624,9 @@
$(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc \
$(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc \
$(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc \
- $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc \
+ $(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc \
+ $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc \
+ $(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc \
$(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc \
test/cpp/codegen/codegen_test_full.cc \
@@ -16547,7 +16644,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/codegen_test_full: protobuf_dep_error
@@ -16568,7 +16665,11 @@
$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/payloads.o: $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
-$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/services.o: $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/benchmark_service.o: $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/report_qps_scenario_service.o: $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/worker_service.o: $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/stats.o: $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
@@ -16581,14 +16682,16 @@
-include $(CODEGEN_TEST_FULL_OBJS:.o=.dep)
endif
endif
-$(OBJDIR)/$(CONFIG)/test/cpp/codegen/codegen_test_full.o: $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/codegen/codegen_test_full.o: $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc
CODEGEN_TEST_MINIMAL_SRC = \
$(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc \
$(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc \
$(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc \
- $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc \
+ $(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc \
+ $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc \
+ $(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc \
$(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc \
test/cpp/codegen/codegen_test_minimal.cc \
src/cpp/codegen/codegen_init.cc \
@@ -16607,7 +16710,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/codegen_test_minimal: protobuf_dep_error
@@ -16628,7 +16731,11 @@
$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/payloads.o: $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
-$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/services.o: $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/benchmark_service.o: $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/report_qps_scenario_service.o: $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/worker_service.o: $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/stats.o: $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
@@ -16643,8 +16750,8 @@
-include $(CODEGEN_TEST_MINIMAL_OBJS:.o=.dep)
endif
endif
-$(OBJDIR)/$(CONFIG)/test/cpp/codegen/codegen_test_minimal.o: $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/src/cpp/codegen/codegen_init.o: $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/codegen/codegen_test_minimal.o: $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/src/cpp/codegen/codegen_init.o: $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc
CREDENTIALS_TEST_SRC = \
@@ -16664,7 +16771,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/credentials_test: protobuf_dep_error
@@ -16707,7 +16814,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/cxx_byte_buffer_test: protobuf_dep_error
@@ -16750,7 +16857,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/cxx_slice_test: protobuf_dep_error
@@ -16793,7 +16900,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/cxx_string_ref_test: protobuf_dep_error
@@ -16836,7 +16943,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/cxx_time_test: protobuf_dep_error
@@ -16879,7 +16986,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/end2end_test: protobuf_dep_error
@@ -16923,7 +17030,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/error_details_test: protobuf_dep_error
@@ -16969,7 +17076,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/exception_test: protobuf_dep_error
@@ -17012,7 +17119,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/filter_end2end_test: protobuf_dep_error
@@ -17055,7 +17162,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/generic_end2end_test: protobuf_dep_error
@@ -17099,7 +17206,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/golden_file_test: protobuf_dep_error
@@ -17145,7 +17252,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/grpc_alts_credentials_options_test: protobuf_dep_error
@@ -17188,7 +17295,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/grpc_cli: protobuf_dep_error
@@ -17223,7 +17330,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/grpc_cpp_plugin: protobuf_dep_error
@@ -17254,7 +17361,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/grpc_csharp_plugin: protobuf_dep_error
@@ -17285,7 +17392,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/grpc_node_plugin: protobuf_dep_error
@@ -17316,7 +17423,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/grpc_objective_c_plugin: protobuf_dep_error
@@ -17347,7 +17454,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/grpc_php_plugin: protobuf_dep_error
@@ -17378,7 +17485,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/grpc_python_plugin: protobuf_dep_error
@@ -17409,7 +17516,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/grpc_ruby_plugin: protobuf_dep_error
@@ -17450,7 +17557,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/grpc_tool_test: protobuf_dep_error
@@ -17499,7 +17606,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/grpclb_api_test: protobuf_dep_error
@@ -17546,7 +17653,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/grpclb_end2end_test: protobuf_dep_error
@@ -17592,7 +17699,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/h2_ssl_cert_test: protobuf_dep_error
@@ -17635,7 +17742,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/h2_ssl_session_reuse_test: protobuf_dep_error
@@ -17678,7 +17785,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/health_service_end2end_test: protobuf_dep_error
@@ -17717,7 +17824,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/http2_client: protobuf_dep_error
@@ -17752,7 +17859,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/hybrid_end2end_test: protobuf_dep_error
@@ -17795,7 +17902,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/inlined_vector_test: protobuf_dep_error
@@ -17838,7 +17945,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/inproc_sync_unary_ping_pong_test: protobuf_dep_error
@@ -17877,7 +17984,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/interop_client: protobuf_dep_error
@@ -17908,7 +18015,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/interop_server: protobuf_dep_error
@@ -17943,7 +18050,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/interop_test: protobuf_dep_error
@@ -17986,7 +18093,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/json_run_localhost: protobuf_dep_error
@@ -18012,6 +18119,49 @@
endif
+LB_LOAD_DATA_STORE_TEST_SRC = \
+ test/cpp/server/load_reporter/load_data_store_test.cc \
+
+LB_LOAD_DATA_STORE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LB_LOAD_DATA_STORE_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/lb_load_data_store_test: openssl_dep_error
+
+else
+
+
+
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
+
+$(BINDIR)/$(CONFIG)/lb_load_data_store_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/lb_load_data_store_test: $(PROTOBUF_DEP) $(LB_LOAD_DATA_STORE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/liblb_load_data_store.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+ $(E) "[LD] Linking $@"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(LDXX) $(LDFLAGS) $(LB_LOAD_DATA_STORE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/liblb_load_data_store.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/lb_load_data_store_test
+
+endif
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/cpp/server/load_reporter/load_data_store_test.o: $(LIBDIR)/$(CONFIG)/liblb_load_data_store.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_lb_load_data_store_test: $(LB_LOAD_DATA_STORE_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(LB_LOAD_DATA_STORE_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
MEMORY_TEST_SRC = \
test/core/gprpp/memory_test.cc \
@@ -18029,7 +18179,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/memory_test: protobuf_dep_error
@@ -18073,7 +18223,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/metrics_client: protobuf_dep_error
@@ -18119,7 +18269,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/mock_test: protobuf_dep_error
@@ -18162,7 +18312,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/nonblocking_test: protobuf_dep_error
@@ -18205,7 +18355,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/noop-benchmark: protobuf_dep_error
@@ -18249,7 +18399,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/orphanable_test: protobuf_dep_error
@@ -18292,7 +18442,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/proto_server_reflection_test: protobuf_dep_error
@@ -18335,7 +18485,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/proto_utils_test: protobuf_dep_error
@@ -18378,7 +18528,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/qps_interarrival_test: protobuf_dep_error
@@ -18421,7 +18571,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/qps_json_driver: protobuf_dep_error
@@ -18464,7 +18614,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/qps_openloop_test: protobuf_dep_error
@@ -18507,7 +18657,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/qps_worker: protobuf_dep_error
@@ -18553,7 +18703,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/reconnect_interop_client: protobuf_dep_error
@@ -18606,7 +18756,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/reconnect_interop_server: protobuf_dep_error
@@ -18656,7 +18806,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/ref_counted_ptr_test: protobuf_dep_error
@@ -18699,7 +18849,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/ref_counted_test: protobuf_dep_error
@@ -18725,6 +18875,49 @@
endif
+RETRY_THROTTLE_TEST_SRC = \
+ test/core/client_channel/retry_throttle_test.cc \
+
+RETRY_THROTTLE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(RETRY_THROTTLE_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/retry_throttle_test: openssl_dep_error
+
+else
+
+
+
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
+
+$(BINDIR)/$(CONFIG)/retry_throttle_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/retry_throttle_test: $(PROTOBUF_DEP) $(RETRY_THROTTLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+ $(E) "[LD] Linking $@"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(LDXX) $(LDFLAGS) $(RETRY_THROTTLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/retry_throttle_test
+
+endif
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/client_channel/retry_throttle_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_retry_throttle_test: $(RETRY_THROTTLE_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(RETRY_THROTTLE_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
SECURE_AUTH_CONTEXT_TEST_SRC = \
test/cpp/common/secure_auth_context_test.cc \
@@ -18742,7 +18935,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/secure_auth_context_test: protobuf_dep_error
@@ -18785,7 +18978,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test: protobuf_dep_error
@@ -18828,7 +19021,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/server_builder_plugin_test: protobuf_dep_error
@@ -18873,7 +19066,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/server_builder_test: protobuf_dep_error
@@ -18904,6 +19097,56 @@
$(OBJDIR)/$(CONFIG)/test/cpp/server/server_builder_test.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc
+SERVER_BUILDER_WITH_SOCKET_MUTATOR_TEST_SRC = \
+ $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc \
+ $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc \
+ test/cpp/server/server_builder_with_socket_mutator_test.cc \
+
+SERVER_BUILDER_WITH_SOCKET_MUTATOR_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SERVER_BUILDER_WITH_SOCKET_MUTATOR_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/server_builder_with_socket_mutator_test: openssl_dep_error
+
+else
+
+
+
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
+
+$(BINDIR)/$(CONFIG)/server_builder_with_socket_mutator_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/server_builder_with_socket_mutator_test: $(PROTOBUF_DEP) $(SERVER_BUILDER_WITH_SOCKET_MUTATOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a
+ $(E) "[LD] Linking $@"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(LDXX) $(LDFLAGS) $(SERVER_BUILDER_WITH_SOCKET_MUTATOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_builder_with_socket_mutator_test
+
+endif
+
+endif
+
+$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo_messages.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+$(OBJDIR)/$(CONFIG)/test/cpp/server/server_builder_with_socket_mutator_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_server_builder_with_socket_mutator_test: $(SERVER_BUILDER_WITH_SOCKET_MUTATOR_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(SERVER_BUILDER_WITH_SOCKET_MUTATOR_TEST_OBJS:.o=.dep)
+endif
+endif
+$(OBJDIR)/$(CONFIG)/test/cpp/server/server_builder_with_socket_mutator_test.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc
+
+
SERVER_CONTEXT_TEST_SPOUSE_TEST_SRC = \
test/cpp/test/server_context_test_spouse_test.cc \
@@ -18921,7 +19164,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/server_context_test_spouse_test: protobuf_dep_error
@@ -18964,7 +19207,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/server_crash_test: protobuf_dep_error
@@ -19007,7 +19250,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/server_crash_test_client: protobuf_dep_error
@@ -19050,7 +19293,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/server_early_return_test: protobuf_dep_error
@@ -19095,7 +19338,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/server_request_call_test: protobuf_dep_error
@@ -19143,7 +19386,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/shutdown_test: protobuf_dep_error
@@ -19186,7 +19429,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/slice_hash_table_test: protobuf_dep_error
@@ -19229,7 +19472,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/slice_weak_hash_table_test: protobuf_dep_error
@@ -19272,7 +19515,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/stats_test: protobuf_dep_error
@@ -19315,7 +19558,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/status_metadata_test: protobuf_dep_error
@@ -19358,7 +19601,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/status_util_test: protobuf_dep_error
@@ -19401,7 +19644,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/streaming_throughput_test: protobuf_dep_error
@@ -19451,7 +19694,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/stress_test: protobuf_dep_error
@@ -19512,7 +19755,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/thread_manager_test: protobuf_dep_error
@@ -19555,7 +19798,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/thread_stress_test: protobuf_dep_error
@@ -19598,7 +19841,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/transport_pid_controller_test: protobuf_dep_error
@@ -19641,7 +19884,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/transport_security_common_api_test: protobuf_dep_error
@@ -19684,7 +19927,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/writes_per_rpc_test: protobuf_dep_error
@@ -19857,7 +20100,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_crypto_test_data: protobuf_dep_error
@@ -19897,7 +20140,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_asn1_test: protobuf_dep_error
@@ -19937,7 +20180,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_base64_test: protobuf_dep_error
@@ -19977,7 +20220,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_bio_test: protobuf_dep_error
@@ -20017,7 +20260,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_buf_test: protobuf_dep_error
@@ -20057,7 +20300,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_bytestring_test: protobuf_dep_error
@@ -20097,7 +20340,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_chacha_test: protobuf_dep_error
@@ -20137,7 +20380,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_aead_test: protobuf_dep_error
@@ -20177,7 +20420,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_cipher_test: protobuf_dep_error
@@ -20217,7 +20460,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_cmac_test: protobuf_dep_error
@@ -20257,7 +20500,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_compiler_test: protobuf_dep_error
@@ -20297,7 +20540,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_constant_time_test: protobuf_dep_error
@@ -20337,7 +20580,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_ed25519_test: protobuf_dep_error
@@ -20377,7 +20620,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_spake25519_test: protobuf_dep_error
@@ -20417,7 +20660,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_x25519_test: protobuf_dep_error
@@ -20457,7 +20700,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_dh_test: protobuf_dep_error
@@ -20497,7 +20740,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_digest_test: protobuf_dep_error
@@ -20537,7 +20780,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_dsa_test: protobuf_dep_error
@@ -20577,7 +20820,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_ecdh_test: protobuf_dep_error
@@ -20617,7 +20860,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_err_test: protobuf_dep_error
@@ -20657,7 +20900,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_evp_extra_test: protobuf_dep_error
@@ -20697,7 +20940,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_evp_test: protobuf_dep_error
@@ -20737,7 +20980,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_pbkdf_test: protobuf_dep_error
@@ -20777,7 +21020,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_scrypt_test: protobuf_dep_error
@@ -20817,7 +21060,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_aes_test: protobuf_dep_error
@@ -20857,7 +21100,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_bn_test: protobuf_dep_error
@@ -20897,7 +21140,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_ec_test: protobuf_dep_error
@@ -20937,7 +21180,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_p256-x86_64_test: protobuf_dep_error
@@ -20977,7 +21220,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_ecdsa_test: protobuf_dep_error
@@ -21017,7 +21260,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_gcm_test: protobuf_dep_error
@@ -21057,7 +21300,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_ctrdrbg_test: protobuf_dep_error
@@ -21097,7 +21340,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_hkdf_test: protobuf_dep_error
@@ -21137,7 +21380,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_hmac_test: protobuf_dep_error
@@ -21177,7 +21420,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_lhash_test: protobuf_dep_error
@@ -21217,7 +21460,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_obj_test: protobuf_dep_error
@@ -21257,7 +21500,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_pkcs7_test: protobuf_dep_error
@@ -21297,7 +21540,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_pkcs12_test: protobuf_dep_error
@@ -21337,7 +21580,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_pkcs8_test: protobuf_dep_error
@@ -21377,7 +21620,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_poly1305_test: protobuf_dep_error
@@ -21417,7 +21660,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_pool_test: protobuf_dep_error
@@ -21457,7 +21700,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_refcount_test: protobuf_dep_error
@@ -21497,7 +21740,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_rsa_test: protobuf_dep_error
@@ -21537,7 +21780,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_file_test_gtest: protobuf_dep_error
@@ -21577,7 +21820,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_gtest_main: protobuf_dep_error
@@ -21617,7 +21860,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_thread_test: protobuf_dep_error
@@ -21657,7 +21900,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_x509_test: protobuf_dep_error
@@ -21697,7 +21940,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_tab_test: protobuf_dep_error
@@ -21737,7 +21980,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_v3name_test: protobuf_dep_error
@@ -21777,7 +22020,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_span_test: protobuf_dep_error
@@ -21817,7 +22060,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/boringssl_ssl_test: protobuf_dep_error
@@ -23051,7 +23294,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/resolver_component_test_unsecure: protobuf_dep_error
@@ -23094,7 +23337,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/resolver_component_test: protobuf_dep_error
@@ -23137,7 +23380,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker_unsecure: protobuf_dep_error
@@ -23180,7 +23423,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker: protobuf_dep_error
@@ -23223,7 +23466,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/address_sorting_test_unsecure: protobuf_dep_error
@@ -23266,7 +23509,7 @@
ifeq ($(NO_PROTOBUF),true)
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/address_sorting_test: protobuf_dep_error
@@ -23292,6 +23535,41 @@
endif
+ALTS_CREDENTIALS_FUZZER_ONE_ENTRY_SRC = \
+ test/core/security/alts_credentials_fuzzer.cc \
+ test/core/util/one_corpus_entry_fuzzer.cc \
+
+ALTS_CREDENTIALS_FUZZER_ONE_ENTRY_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(ALTS_CREDENTIALS_FUZZER_ONE_ENTRY_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/alts_credentials_fuzzer_one_entry: openssl_dep_error
+
+else
+
+
+
+$(BINDIR)/$(CONFIG)/alts_credentials_fuzzer_one_entry: $(ALTS_CREDENTIALS_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+ $(E) "[LD] Linking $@"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(LD) $(LDFLAGS) $(ALTS_CREDENTIALS_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/alts_credentials_fuzzer_one_entry
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/security/alts_credentials_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_alts_credentials_fuzzer_one_entry: $(ALTS_CREDENTIALS_FUZZER_ONE_ENTRY_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(ALTS_CREDENTIALS_FUZZER_ONE_ENTRY_OBJS:.o=.dep)
+endif
+endif
+
+
API_FUZZER_ONE_ENTRY_SRC = \
test/core/end2end/fuzzers/api_fuzzer.cc \
test/core/util/one_corpus_entry_fuzzer.cc \
@@ -23827,7 +24105,6 @@
src/core/tsi/ssl/session_cache/ssl_session_openssl.cc: $(OPENSSL_DEP)
src/core/tsi/ssl_transport_security.cc: $(OPENSSL_DEP)
src/core/tsi/transport_security.cc: $(OPENSSL_DEP)
-src/core/tsi/transport_security_adapter.cc: $(OPENSSL_DEP)
src/core/tsi/transport_security_grpc.cc: $(OPENSSL_DEP)
src/cpp/client/cronet_credentials.cc: $(OPENSSL_DEP)
src/cpp/client/secure_credentials.cc: $(OPENSSL_DEP)
@@ -23837,6 +24114,7 @@
src/cpp/common/secure_create_auth_context.cc: $(OPENSSL_DEP)
src/cpp/ext/proto_server_reflection.cc: $(OPENSSL_DEP)
src/cpp/ext/proto_server_reflection_plugin.cc: $(OPENSSL_DEP)
+src/cpp/server/load_reporter/load_data_store.cc: $(OPENSSL_DEP)
src/cpp/server/secure_server_credentials.cc: $(OPENSSL_DEP)
src/cpp/util/core_stats.cc: $(OPENSSL_DEP)
src/cpp/util/error_details.cc: $(OPENSSL_DEP)
diff --git a/PYTHON-MANIFEST.in b/PYTHON-MANIFEST.in
index 8be0af9..b30a1fb 100644
--- a/PYTHON-MANIFEST.in
+++ b/PYTHON-MANIFEST.in
@@ -4,10 +4,11 @@
graft src/core
graft src/boringssl
graft include/grpc
+graft third_party/address_sorting
graft third_party/boringssl
+graft third_party/cares
graft third_party/nanopb
graft third_party/zlib
-graft third_party/cares
include src/python/grpcio/_spawn_patch.py
include src/python/grpcio/commands.py
include src/python/grpcio/grpc_version.py
diff --git a/README.md b/README.md
index e66c0b1..21a9910 100644
--- a/README.md
+++ b/README.md
@@ -39,6 +39,7 @@
| Java | [grpc-java](http://github.com/grpc/grpc-java) |
| Go | [grpc-go](http://github.com/grpc/grpc-go) |
| NodeJS | [grpc-node](https://github.com/grpc/grpc-node) |
+| WebJS | [grpc-web](https://github.com/grpc/grpc-web) |
| Dart | [grpc-dart](https://github.com/grpc/grpc-dart) |
See [MANIFEST.md](MANIFEST.md) for a listing of top-level items in the
diff --git a/Rakefile b/Rakefile
index 1eac37d..0068a3b 100755
--- a/Rakefile
+++ b/Rakefile
@@ -23,6 +23,12 @@
# Add the extension compiler task
Rake::ExtensionTask.new('grpc_c', spec) do |ext|
+ unless RUBY_PLATFORM =~ /darwin/
+ # TODO: also set "no_native to true" for mac if possible. As is,
+ # "no_native" can only be set if the RUBY_PLATFORM doing
+ # cross-compilation is contained in the "ext.cross_platform" array.
+ ext.no_native = true
+ end
ext.source_pattern = '**/*.{c,h}'
ext.ext_dir = File.join('src', 'ruby', 'ext', 'grpc')
ext.lib_dir = File.join('src', 'ruby', 'lib', 'grpc')
diff --git a/bazel/generate_cc.bzl b/bazel/generate_cc.bzl
index e610123..ae747aa 100644
--- a/bazel/generate_cc.bzl
+++ b/bazel/generate_cc.bzl
@@ -10,7 +10,16 @@
includes = [f for src in ctx.attr.srcs for f in src.proto.transitive_imports]
outs = []
# label_len is length of the path from WORKSPACE root to the location of this build file
- label_len = len(ctx.label.package) + 1
+ label_len = 0
+ # proto_root is the directory relative to which generated include paths should be
+ proto_root = ""
+ if ctx.label.package:
+ # The +1 is for the trailing slash.
+ label_len += len(ctx.label.package) + 1
+ if ctx.label.workspace_root:
+ label_len += len(ctx.label.workspace_root) + 1
+ proto_root = "/" + ctx.label.workspace_root
+
if ctx.executable.plugin:
outs += [proto.path[label_len:-len(".proto")] + ".grpc.pb.h" for proto in protos]
outs += [proto.path[label_len:-len(".proto")] + ".grpc.pb.cc" for proto in protos]
@@ -20,7 +29,7 @@
outs += [proto.path[label_len:-len(".proto")] + ".pb.h" for proto in protos]
outs += [proto.path[label_len:-len(".proto")] + ".pb.cc" for proto in protos]
out_files = [ctx.new_file(out) for out in outs]
- dir_out = str(ctx.genfiles_dir.path)
+ dir_out = str(ctx.genfiles_dir.path + proto_root)
arguments = []
if ctx.executable.plugin:
@@ -33,7 +42,20 @@
else:
arguments += ["--cpp_out=" + ",".join(ctx.attr.flags) + ":" + dir_out]
additional_input = []
- arguments += ["-I{0}={0}".format(include.path) for include in includes]
+
+ # Import protos relative to their workspace root so that protoc prints the
+ # right include paths.
+ for include in includes:
+ directory = include.path
+ if directory.startswith("external"):
+ external_sep = directory.find("/")
+ repository_sep = directory.find("/", external_sep + 1)
+ arguments += ["--proto_path=" + directory[:repository_sep]]
+ else:
+ arguments += ["--proto_path=."]
+ # Include the output directory so that protoc puts the generated code in the
+ # right directory.
+ arguments += ["--proto_path={0}{1}".format(dir_out, proto_root)]
arguments += [proto.path for proto in protos]
# create a list of well known proto files if the argument is non-None
diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl
index a441c3f..3c69a6b 100644
--- a/bazel/grpc_deps.bzl
+++ b/bazel/grpc_deps.bzl
@@ -57,6 +57,16 @@
actual = "@com_github_gflags_gflags//:gflags",
)
+ native.bind(
+ name = "grpc_cpp_plugin",
+ actual = "@com_github_grpc_grpc//:grpc_cpp_plugin"
+ )
+
+ native.bind(
+ name = "grpc++_codegen_proto",
+ actual = "@com_github_grpc_grpc//:grpc++_codegen_proto"
+ )
+
if "boringssl" not in native.existing_rules():
native.http_archive(
name = "boringssl",
@@ -75,8 +85,8 @@
if "com_google_protobuf" not in native.existing_rules():
native.http_archive(
name = "com_google_protobuf",
- strip_prefix = "protobuf-2761122b810fe8861004ae785cc3ab39f384d342",
- url = "https://github.com/google/protobuf/archive/2761122b810fe8861004ae785cc3ab39f384d342.tar.gz",
+ strip_prefix = "protobuf-b5fbb742af122b565925987e65c08957739976a7",
+ url = "https://github.com/google/protobuf/archive/b5fbb742af122b565925987e65c08957739976a7.tar.gz",
)
if "com_github_google_googletest" not in native.existing_rules():
@@ -120,12 +130,12 @@
if "com_github_bazelbuild_bazeltoolchains" not in native.existing_rules():
native.http_archive(
name = "com_github_bazelbuild_bazeltoolchains",
- strip_prefix = "bazel-toolchains-b850ccdf53fed1ccab7670f52d6b297d74348d1b",
+ strip_prefix = "bazel-toolchains-44200e0c026d86c53470d107b3697a3e46469c43",
urls = [
- "https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/b850ccdf53fed1ccab7670f52d6b297d74348d1b.tar.gz",
- "https://github.com/bazelbuild/bazel-toolchains/archive/b850ccdf53fed1ccab7670f52d6b297d74348d1b.tar.gz",
+ "https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/44200e0c026d86c53470d107b3697a3e46469c43.tar.gz",
+ "https://github.com/bazelbuild/bazel-toolchains/archive/44200e0c026d86c53470d107b3697a3e46469c43.tar.gz",
],
- sha256 = "d84d6b2fe88ef99963febf91ddce33503eed14c155ace922e2122271b483be64",
+ sha256 = "699b55a6916c687f4b7dc092dbbf5f64672cde0dc965f79717735ec4e5416556",
)
# TODO: move some dependencies from "grpc_deps" here?
diff --git a/build.yaml b/build.yaml
index 88f2283..1bc2adb 100644
--- a/build.yaml
+++ b/build.yaml
@@ -13,8 +13,8 @@
'#09': Per-language overrides are possible with (eg) ruby_version tag here
'#10': See the expand_version.py for all the quirks here
core_version: 6.0.0-dev
- g_stands_for: gorgeous
- version: 1.11.0-dev
+ g_stands_for: gloriosa
+ version: 1.13.0-dev
filegroups:
- name: alts_proto
headers:
@@ -70,6 +70,8 @@
- tsi_interface
- tsi
- name: alts_util
+ public_headers:
+ - include/grpc/grpc_security.h
headers:
- src/core/lib/security/credentials/alts/check_gcp_environment.h
- src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h
@@ -534,6 +536,14 @@
uses:
- grpc_codegen
- grpc_trace_headers
+- name: grpc_client_authority_filter
+ headers:
+ - src/core/ext/filters/http/client_authority_filter.h
+ src:
+ - src/core/ext/filters/http/client_authority_filter.cc
+ plugin: grpc_client_authority_filter
+ uses:
+ - grpc_base
- name: grpc_client_channel
headers:
- src/core/ext/filters/client_channel/backup_poller.h
@@ -618,6 +628,7 @@
- name: grpc_lb_policy_grpclb
headers:
- src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h
+ - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h
- src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h
- src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h
- src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h
@@ -638,6 +649,7 @@
- name: grpc_lb_policy_grpclb_secure
headers:
- src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h
+ - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h
- src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h
- src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h
- src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h
@@ -675,8 +687,6 @@
- name: grpc_lb_subchannel_list
headers:
- src/core/ext/filters/client_channel/lb_policy/subchannel_list.h
- src:
- - src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc
uses:
- grpc_base
- grpc_client_channel
@@ -736,6 +746,7 @@
public_headers:
- include/grpc/grpc_security.h
headers:
+ - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h
- src/core/lib/security/context/security_context.h
- src/core/lib/security/credentials/alts/alts_credentials.h
- src/core/lib/security/credentials/composite/composite_credentials.h
@@ -816,6 +827,7 @@
- test/core/end2end/fixtures/proxy.h
- test/core/iomgr/endpoint_tests.h
- test/core/util/debugger_macros.h
+ - test/core/util/fuzzer_util.h
- test/core/util/grpc_profiler.h
- test/core/util/histogram.h
- test/core/util/memory_counters.h
@@ -835,6 +847,7 @@
- test/core/end2end/fixtures/proxy.cc
- test/core/iomgr/endpoint_tests.cc
- test/core/util/debugger_macros.cc
+ - test/core/util/fuzzer_util.cc
- test/core/util/grpc_profiler.cc
- test/core/util/histogram.cc
- test/core/util/memory_counters.cc
@@ -929,8 +942,10 @@
- gpr
- name: grpc_transport_chttp2_client_connector
headers:
+ - src/core/ext/transport/chttp2/client/authority.h
- src/core/ext/transport/chttp2/client/chttp2_connector.h
src:
+ - src/core/ext/transport/chttp2/client/authority.cc
- src/core/ext/transport/chttp2/client/chttp2_connector.cc
uses:
- grpc_transport_chttp2
@@ -1065,11 +1080,9 @@
- name: tsi_interface
headers:
- src/core/tsi/transport_security.h
- - src/core/tsi/transport_security_adapter.h
- src/core/tsi/transport_security_interface.h
src:
- src/core/tsi/transport_security.cc
- - src/core/tsi/transport_security_adapter.cc
deps:
- gpr
secure: true
@@ -1154,6 +1167,8 @@
language: c++
public_headers:
- include/grpc++/impl/codegen/proto_utils.h
+ - include/grpcpp/impl/codegen/proto_buffer_reader.h
+ - include/grpcpp/impl/codegen/proto_buffer_writer.h
- include/grpcpp/impl/codegen/proto_utils.h
uses:
- grpc++_codegen_base
@@ -1244,6 +1259,8 @@
- include/grpcpp/support/byte_buffer.h
- include/grpcpp/support/channel_arguments.h
- include/grpcpp/support/config.h
+ - include/grpcpp/support/proto_buffer_reader.h
+ - include/grpcpp/support/proto_buffer_writer.h
- include/grpcpp/support/slice.h
- include/grpcpp/support/status.h
- include/grpcpp/support/status_code_enum.h
@@ -1290,7 +1307,6 @@
- src/cpp/server/server_posix.cc
- src/cpp/thread_manager/thread_manager.cc
- src/cpp/util/byte_buffer_cc.cc
- - src/cpp/util/slice_cc.cc
- src/cpp/util/status.cc
- src/cpp/util/string_ref.cc
- src/cpp/util/time_cc.cc
@@ -1389,6 +1405,7 @@
- grpc_max_age_filter
- grpc_message_size_filter
- grpc_deadline_filter
+ - grpc_client_authority_filter
- grpc_workaround_cronet_compression_filter
- grpc_server_backward_compatibility
generate_plugin_registry: true
@@ -1407,17 +1424,9 @@
dll: true
filegroups:
- grpc_base
- - grpc_base_headers
- - grpc_deadline_filter
- - grpc_lb_policy_pick_first
- - grpc_max_age_filter
- - grpc_message_size_filter
- - grpc_resolver_dns_native
- - grpc_resolver_sockaddr
- - grpc_server_load_reporting
- grpc_transport_cronet_client_secure
- grpc_transport_chttp2_client_secure
- - grpc_transport_chttp2_server_secure
+ - grpc_server_load_reporting
generate_plugin_registry: true
platforms:
- linux
@@ -1499,6 +1508,7 @@
- grpc_max_age_filter
- grpc_message_size_filter
- grpc_deadline_filter
+ - grpc_client_authority_filter
- grpc_workaround_cronet_compression_filter
- grpc_server_backward_compatibility
generate_plugin_registry: true
@@ -1881,6 +1891,15 @@
- test/cpp/interop/interop_server_bootstrap.cc
deps:
- interop_server_lib
+- name: lb_load_data_store
+ build: private
+ language: c++
+ headers:
+ - src/cpp/server/load_reporter/load_data_store.h
+ src:
+ - src/cpp/server/load_reporter/load_data_store.cc
+ deps:
+ - grpc++
- name: qps
build: private
language: c++
@@ -1901,7 +1920,9 @@
- src/proto/grpc/testing/payloads.proto
- src/proto/grpc/testing/stats.proto
- src/proto/grpc/testing/control.proto
- - src/proto/grpc/testing/services.proto
+ - src/proto/grpc/testing/benchmark_service.proto
+ - src/proto/grpc/testing/report_qps_scenario_service.proto
+ - src/proto/grpc/testing/worker_service.proto
- test/cpp/qps/benchmark_config.cc
- test/cpp/qps/client_async.cc
- test/cpp/qps/client_sync.cc
@@ -1970,6 +1991,19 @@
- grpc
- gpr_test_util
- gpr
+- name: alts_credentials_fuzzer
+ build: fuzzer
+ language: c
+ src:
+ - test/core/security/alts_credentials_fuzzer.cc
+ deps:
+ - grpc_test_util
+ - grpc
+ - gpr_test_util
+ - gpr
+ corpus_dirs:
+ - test/core/security/corpus/alts_credentials_corpus
+ maxlen: 2048
- name: api_fuzzer
build: fuzzer
language: c
@@ -2613,17 +2647,6 @@
- grpc
- gpr_test_util
- gpr
-- name: grpc_invalid_channel_args_test
- build: test
- language: c
- src:
- - test/core/surface/invalid_channel_args_test.cc
- deps:
- - grpc_test_util
- - grpc
- - gpr_test_util
- - gpr
- uses_polling: false
- name: grpc_json_token_test
build: test
language: c
@@ -3812,6 +3835,7 @@
- grpc_unsecure
- gpr_test_util
- gpr
+ - grpc++_test_config
benchmark: true
defaults: benchmark
platforms:
@@ -3833,6 +3857,7 @@
- grpc_unsecure
- gpr_test_util
- gpr
+ - grpc++_test_config
benchmark: true
defaults: benchmark
platforms:
@@ -3854,6 +3879,7 @@
- grpc_unsecure
- gpr_test_util
- gpr
+ - grpc++_test_config
benchmark: true
defaults: benchmark
platforms:
@@ -3875,6 +3901,7 @@
- grpc_unsecure
- gpr_test_util
- gpr
+ - grpc++_test_config
benchmark: true
defaults: benchmark
platforms:
@@ -3895,6 +3922,7 @@
- grpc_unsecure
- gpr_test_util
- gpr
+ - grpc++_test_config
benchmark: true
defaults: benchmark
platforms:
@@ -3915,6 +3943,7 @@
- grpc_unsecure
- gpr_test_util
- gpr
+ - grpc++_test_config
benchmark: true
defaults: benchmark
platforms:
@@ -3935,6 +3964,7 @@
- grpc_unsecure
- gpr_test_util
- gpr
+ - grpc++_test_config
benchmark: true
defaults: benchmark
platforms:
@@ -3955,6 +3985,7 @@
- grpc_unsecure
- gpr_test_util
- gpr
+ - grpc++_test_config
benchmark: true
defaults: benchmark
platforms:
@@ -3978,6 +4009,7 @@
- grpc_unsecure
- gpr_test_util
- gpr
+ - grpc++_test_config
benchmark: true
defaults: benchmark
excluded_poll_engines:
@@ -4004,6 +4036,7 @@
- grpc_unsecure
- gpr_test_util
- gpr
+ - grpc++_test_config
benchmark: true
defaults: benchmark
excluded_poll_engines:
@@ -4057,6 +4090,7 @@
- grpc_unsecure
- gpr_test_util
- gpr
+ - grpc++_test_config
benchmark: true
defaults: benchmark
excluded_poll_engines:
@@ -4081,6 +4115,7 @@
- grpc_unsecure
- gpr_test_util
- gpr
+ - grpc++_test_config
benchmark: true
defaults: benchmark
platforms:
@@ -4102,6 +4137,7 @@
- grpc_unsecure
- gpr_test_util
- gpr
+ - grpc++_test_config
benchmark: true
defaults: benchmark
platforms:
@@ -4268,7 +4304,9 @@
- src/proto/grpc/testing/control.proto
- src/proto/grpc/testing/messages.proto
- src/proto/grpc/testing/payloads.proto
- - src/proto/grpc/testing/services.proto
+ - src/proto/grpc/testing/benchmark_service.proto
+ - src/proto/grpc/testing/report_qps_scenario_service.proto
+ - src/proto/grpc/testing/worker_service.proto
- src/proto/grpc/testing/stats.proto
- test/cpp/codegen/codegen_test_full.cc
deps:
@@ -4287,7 +4325,9 @@
- src/proto/grpc/testing/control.proto
- src/proto/grpc/testing/messages.proto
- src/proto/grpc/testing/payloads.proto
- - src/proto/grpc/testing/services.proto
+ - src/proto/grpc/testing/benchmark_service.proto
+ - src/proto/grpc/testing/report_qps_scenario_service.proto
+ - src/proto/grpc/testing/worker_service.proto
- src/proto/grpc/testing/stats.proto
- test/cpp/codegen/codegen_test_minimal.cc
deps:
@@ -4749,6 +4789,20 @@
- mac
- linux
- posix
+- name: lb_load_data_store_test
+ gtest: true
+ build: test
+ language: c++
+ src:
+ - test/cpp/server/load_reporter/load_data_store_test.cc
+ deps:
+ - lb_load_data_store
+ - grpc++_test_util
+ - grpc_test_util
+ - grpc++
+ - grpc
+ - gpr_test_util
+ - gpr
- name: memory_test
gtest: true
build: test
@@ -4996,6 +5050,18 @@
- gpr
uses:
- grpc++_test
+- name: retry_throttle_test
+ gtest: true
+ build: test
+ language: c++
+ src:
+ - test/core/client_channel/retry_throttle_test.cc
+ deps:
+ - grpc_test_util
+ - grpc
+ - gpr_test_util
+ - gpr
+ uses_polling: false
- name: secure_auth_context_test
gtest: true
build: test
@@ -5056,6 +5122,23 @@
- grpc++_unsecure
- grpc_unsecure
- gpr
+- name: server_builder_with_socket_mutator_test
+ gtest: true
+ build: test
+ language: c++
+ src:
+ - src/proto/grpc/testing/echo_messages.proto
+ - src/proto/grpc/testing/echo.proto
+ - test/cpp/server/server_builder_with_socket_mutator_test.cc
+ deps:
+ - grpc++_test_util_unsecure
+ - grpc_test_util_unsecure
+ - gpr_test_util
+ - grpc++_unsecure
+ - grpc_unsecure
+ - gpr
+ platforms:
+ - posix
- name: server_context_test_spouse_test
gtest: true
build: test
diff --git a/config.m4 b/config.m4
index d7cda0b..ee2aca4 100644
--- a/config.m4
+++ b/config.m4
@@ -8,6 +8,7 @@
PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/include)
PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/src/php/ext/grpc)
PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/third_party/boringssl/include)
+ PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/third_party/address_sorting/include)
LIBS="-lpthread $LIBS"
@@ -320,9 +321,9 @@
third_party/nanopb/pb_decode.c \
third_party/nanopb/pb_encode.c \
src/core/tsi/transport_security.cc \
- src/core/tsi/transport_security_adapter.cc \
src/core/ext/transport/chttp2/client/insecure/channel_create.cc \
src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc \
+ src/core/ext/transport/chttp2/client/authority.cc \
src/core/ext/transport/chttp2/client/chttp2_connector.cc \
src/core/ext/filters/client_channel/backup_poller.cc \
src/core/ext/filters/client_channel/channel_connectivity.cc \
@@ -367,7 +368,6 @@
src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \
src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc \
src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc \
- src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc \
src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc \
@@ -380,6 +380,7 @@
src/core/ext/census/grpc_context.cc \
src/core/ext/filters/max_age/max_age_filter.cc \
src/core/ext/filters/message_size/message_size_filter.cc \
+ src/core/ext/filters/http/client_authority_filter.cc \
src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc \
src/core/ext/filters/workarounds/workaround_utils.cc \
src/core/plugin_registry/grpc_plugin_registry.cc \
@@ -647,7 +648,6 @@
PHP_ADD_BUILD_DIR($ext_builddir/src/boringssl)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/census)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel)
- PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/grpclb)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/pick_first)
diff --git a/config.w32 b/config.w32
index 5e80781..abca8e2 100644
--- a/config.w32
+++ b/config.w32
@@ -297,9 +297,9 @@
"third_party\\nanopb\\pb_decode.c " +
"third_party\\nanopb\\pb_encode.c " +
"src\\core\\tsi\\transport_security.cc " +
- "src\\core\\tsi\\transport_security_adapter.cc " +
"src\\core\\ext\\transport\\chttp2\\client\\insecure\\channel_create.cc " +
"src\\core\\ext\\transport\\chttp2\\client\\insecure\\channel_create_posix.cc " +
+ "src\\core\\ext\\transport\\chttp2\\client\\authority.cc " +
"src\\core\\ext\\transport\\chttp2\\client\\chttp2_connector.cc " +
"src\\core\\ext\\filters\\client_channel\\backup_poller.cc " +
"src\\core\\ext\\filters\\client_channel\\channel_connectivity.cc " +
@@ -344,7 +344,6 @@
"src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\proto\\grpc\\lb\\v1\\load_balancer.pb.c " +
"src\\core\\ext\\filters\\client_channel\\resolver\\fake\\fake_resolver.cc " +
"src\\core\\ext\\filters\\client_channel\\lb_policy\\pick_first\\pick_first.cc " +
- "src\\core\\ext\\filters\\client_channel\\lb_policy\\subchannel_list.cc " +
"src\\core\\ext\\filters\\client_channel\\lb_policy\\round_robin\\round_robin.cc " +
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\dns_resolver_ares.cc " +
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_ev_driver_posix.cc " +
@@ -357,6 +356,7 @@
"src\\core\\ext\\census\\grpc_context.cc " +
"src\\core\\ext\\filters\\max_age\\max_age_filter.cc " +
"src\\core\\ext\\filters\\message_size\\message_size_filter.cc " +
+ "src\\core\\ext\\filters\\http\\client_authority_filter.cc " +
"src\\core\\ext\\filters\\workarounds\\workaround_cronet_compression_filter.cc " +
"src\\core\\ext\\filters\\workarounds\\workaround_utils.cc " +
"src\\core\\plugin_registry\\grpc_plugin_registry.cc " +
@@ -635,11 +635,13 @@
EXTENSION("grpc", grpc_source, null,
"/DOPENSSL_NO_ASM /D_GNU_SOURCE /DWIN32_LEAN_AND_MEAN "+
"/D_HAS_EXCEPTIONS=0 /DNOMINMAX /DGRPC_ARES=0 /D_WIN32_WINNT=0x600 "+
+ "/DPB_FIELD_16BIT "+
"/I"+configure_module_dirname+" "+
"/I"+configure_module_dirname+"\\include "+
"/I"+configure_module_dirname+"\\src\\php\\ext\\grpc "+
"/I"+configure_module_dirname+"\\third_party\\boringssl\\include "+
- "/I"+configure_module_dirname+"\\third_party\\zlib");
+ "/I"+configure_module_dirname+"\\third_party\\zlib "+
+ "/I"+configure_module_dirname+"\\third_party\\address_sorting\\include");
base_dir = get_define('BUILD_DIR');
FSO.CreateFolder(base_dir+"\\ext");
diff --git a/doc/PROTOCOL-WEB.md b/doc/PROTOCOL-WEB.md
index c31a048..5100c9b 100644
--- a/doc/PROTOCOL-WEB.md
+++ b/doc/PROTOCOL-WEB.md
@@ -29,7 +29,7 @@
* evolve over time, mainly to optimize for browser clients or support
web-specific features such as CORS, XSRF
* become optional (in 1-2 years) when browsers are able to speak the native
-gRPC protocol via the new [whatwg fetch/streams API](https://github.com/whatwg/fetch)
+gRPC protocol via the new [whatwg streams API](https://github.com/whatwg/streams)
# Protocol differences vs [gRPC over HTTP2](PROTOCOL-HTTP2.md)
@@ -106,19 +106,6 @@
# Other features
-Compression
-
-* Full-body compression is supported and expected for all unary
-requests/responses. The compression/decompression will be done
-by browsers, using standard Content-Encoding headers
- * “grpc-encoding” header is not used
- * SDCH, Brotli will be supported
-* Message-level compression for streamed requests/responses is not supported
-because manual compression/decompression is prohibitively expensive using JS
- * Per-message compression may be feasible in future with wasm
-
----
-
Retries, caching
* Will spec out the support after their respective gRPC spec extensions
@@ -128,24 +115,6 @@
---
-Security
-
-* XSRF, XSS etc to be specified
-
----
-
-CORS preflight
-
-* Should follow the [CORS spec](https://developer.mozilla.org/en-US/docs/Web/HTTP/Server-Side_Access_Control)
- * Access-Control-Allow-Credentials to allow Authorization headers
- * Access-Control-Allow-Methods to allow POST and (preflight) OPTIONS only
- * Access-Control-Allow-Headers to whatever the preflight request carries
-* The client library may support header overwrites to avoid preflight
- * https://github.com/whatwg/fetch/issues/210
-* CSP support to be specified
-
----
-
Keep-alive
* HTTP/2 PING is not supported or used
@@ -165,3 +134,8 @@
* Special headers may be introduced to support features that may break compatiblity.
+---
+
+Browser-specific features
+
+* For features that are unique to browser or HTML clients, check the [spec doc](https://github.com/grpc/grpc-web/blob/master/PROTOCOL-WEB.md) published in the grpc/grpc-web repo.
diff --git a/doc/environment_variables.md b/doc/environment_variables.md
index ed46a48..587ab83 100644
--- a/doc/environment_variables.md
+++ b/doc/environment_variables.md
@@ -50,6 +50,7 @@
- channel_stack_builder - traces information about channel stacks being built
- executor - traces grpc's internal thread pool ('the executor')
- glb - traces the grpclb load balancer
+ - handshaker - traces handshaking state
- http - traces state in the http2 transport engine
- http2_stream_state - traces all http2 stream state mutations.
- http1 - traces HTTP/1.x operations performed by gRPC
diff --git a/doc/g_stands_for.md b/doc/g_stands_for.md
index 47ae7c5..8b9cf91 100644
--- a/doc/g_stands_for.md
+++ b/doc/g_stands_for.md
@@ -1,17 +1,15 @@
-Each version of gRPC gets a new description of what the 'g' stands for, since
-we've never really been able to figure it out.
+'g' stands for something different every gRPC release:
-Below is a list of already-used definitions (that should not be repeated in the
-future), and the corresponding version numbers that used them:
-
-- 1.0 'g' stands for 'gRPC'
-- 1.1 'g' stands for 'good'
-- 1.2 'g' stands for 'green'
-- 1.3 'g' stands for 'gentle'
-- 1.4 'g' stands for 'gregarious'
-- 1.6 'g' stands for 'garcia'
-- 1.7 'g' stands for 'gambit'
-- 1.8 'g' stands for 'generous'
-- 1.9 'g' stands for 'glossy'
-- 1.10 'g' stands for 'glamorous'
-- 1.11 'g' stands for 'gorgeous'
+- 1.0 'g' stands for ['gRPC'](https://github.com/grpc/grpc/tree/v1.0.x)
+- 1.1 'g' stands for ['good'](https://github.com/grpc/grpc/tree/v1.1.x)
+- 1.2 'g' stands for ['green'](https://github.com/grpc/grpc/tree/v1.2.x)
+- 1.3 'g' stands for ['gentle'](https://github.com/grpc/grpc/tree/v1.3.x)
+- 1.4 'g' stands for ['gregarious'](https://github.com/grpc/grpc/tree/v1.4.x)
+- 1.6 'g' stands for ['garcia'](https://github.com/grpc/grpc/tree/v1.6.x)
+- 1.7 'g' stands for ['gambit'](https://github.com/grpc/grpc/tree/v1.7.x)
+- 1.8 'g' stands for ['generous'](https://github.com/grpc/grpc/tree/v1.8.x)
+- 1.9 'g' stands for ['glossy'](https://github.com/grpc/grpc/tree/v1.9.x)
+- 1.10 'g' stands for ['glamorous'](https://github.com/grpc/grpc/tree/v1.10.x)
+- 1.11 'g' stands for ['gorgeous'](https://github.com/grpc/grpc/tree/v1.11.x)
+- 1.12 'g' stands for ['glorious'](https://github.com/grpc/grpc/tree/v1.12.x)
+- 1.13 'g' stands for ['gloriosa'](https://github.com/grpc/grpc/tree/master)
diff --git a/etc/roots.pem b/etc/roots.pem
index 15d819b..5dbd1ae 100644
--- a/etc/roots.pem
+++ b/etc/roots.pem
@@ -3525,39 +3525,6 @@
5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su
-----END CERTIFICATE-----
-# Issuer: CN=TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H5 O=TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş.
-# Subject: CN=TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H5 O=TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş.
-# Label: "TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H5"
-# Serial: 156233699172481
-# MD5 Fingerprint: da:70:8e:f0:22:df:93:26:f6:5f:9f:d3:15:06:52:4e
-# SHA1 Fingerprint: c4:18:f6:4d:46:d1:df:00:3d:27:30:13:72:43:a9:12:11:c6:75:fb
-# SHA256 Fingerprint: 49:35:1b:90:34:44:c1:85:cc:dc:5c:69:3d:24:d8:55:5c:b2:08:d6:a8:14:13:07:69:9f:4a:f0:63:19:9d:78
------BEGIN CERTIFICATE-----
-MIIEJzCCAw+gAwIBAgIHAI4X/iQggTANBgkqhkiG9w0BAQsFADCBsTELMAkGA1UE
-BhMCVFIxDzANBgNVBAcMBkFua2FyYTFNMEsGA1UECgxEVMOcUktUUlVTVCBCaWxn
-aSDEsGxldGnFn2ltIHZlIEJpbGnFn2ltIEfDvHZlbmxpxJ9pIEhpem1ldGxlcmkg
-QS7Fni4xQjBABgNVBAMMOVTDnFJLVFJVU1QgRWxla3Ryb25payBTZXJ0aWZpa2Eg
-SGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSBINTAeFw0xMzA0MzAwODA3MDFaFw0yMzA0
-MjgwODA3MDFaMIGxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMU0wSwYD
-VQQKDERUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8
-dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLjFCMEAGA1UEAww5VMOcUktUUlVTVCBF
-bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIEg1MIIB
-IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApCUZ4WWe60ghUEoI5RHwWrom
-/4NZzkQqL/7hzmAD/I0Dpe3/a6i6zDQGn1k19uwsu537jVJp45wnEFPzpALFp/kR
-Gml1bsMdi9GYjZOHp3GXDSHHmflS0yxjXVW86B8BSLlg/kJK9siArs1mep5Fimh3
-4khon6La8eHBEJ/rPCmBp+EyCNSgBbGM+42WAA4+Jd9ThiI7/PS98wl+d+yG6w8z
-5UNP9FR1bSmZLmZaQ9/LXMrI5Tjxfjs1nQ/0xVqhzPMggCTTV+wVunUlm+hkS7M0
-hO8EuPbJbKoCPrZV4jI3X/xml1/N1p7HIL9Nxqw/dV8c7TKcfGkAaZHjIxhT6QID
-AQABo0IwQDAdBgNVHQ4EFgQUVpkHHtOsDGlktAxQR95DLL4gwPswDgYDVR0PAQH/
-BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAJ5FdnsX
-SDLyOIspve6WSk6BGLFRRyDN0GSxDsnZAdkJzsiZ3GglE9Rc8qPoBP5yCccLqh0l
-VX6Wmle3usURehnmp349hQ71+S4pL+f5bFgWV1Al9j4uPqrtd3GqqpmWRgqujuwq
-URawXs3qZwQcWDD1YIq9pr1N5Za0/EKJAWv2cMhQOQwt1WbZyNKzMrcbGW3LM/nf
-peYVhDfwwvJllpKQd/Ct9JDpEXjXk4nAPQu6KfTomZ1yju2dL+6SfaHx/126M2CF
-Yv4HAqGEVka+lgqaE9chTLd8B59OTj+RdPsnnRHM3eaxynFNExc5JsUpISuTKWqW
-+qtB4Uu2NQvAmxU=
------END CERTIFICATE-----
-
# Issuer: CN=Certinomis - Root CA O=Certinomis OU=0002 433998903
# Subject: CN=Certinomis - Root CA O=Certinomis OU=0002 433998903
# Label: "Certinomis - Root CA"
diff --git a/examples/android/helloworld/app/CMakeLists.txt b/examples/android/helloworld/app/CMakeLists.txt
index 6ee18da..f449a5c 100644
--- a/examples/android/helloworld/app/CMakeLists.txt
+++ b/examples/android/helloworld/app/CMakeLists.txt
@@ -12,36 +12,6 @@
add_subdirectory(${GRPC_SRC_DIR} ${GRPC_BUILD_DIR})
-include_directories(${GRPC_SRC_DIR}/include)
-
-add_library(libgrpc STATIC IMPORTED)
-set_target_properties(libgrpc PROPERTIES IMPORTED_LOCATION
- ${GRPC_BUILD_DIR}/libgrpc.a)
-
-add_library(libgrpc++ STATIC IMPORTED)
-set_target_properties(libgrpc++ PROPERTIES IMPORTED_LOCATION
- ${GRPC_BUILD_DIR}/libgrpc++.a)
-
-add_library(libgpr STATIC IMPORTED)
-set_target_properties(libgpr PROPERTIES IMPORTED_LOCATION
- ${GRPC_BUILD_DIR}/libgpr.a)
-
-add_library(libcares STATIC IMPORTED)
-set_target_properties(libcares PROPERTIES IMPORTED_LOCATION
- ${GRPC_BUILD_DIR}/third_party/cares/cares/lib/libcares.a)
-
-add_library(libzlib STATIC IMPORTED)
-set_target_properties(libzlib PROPERTIES IMPORTED_LOCATION
- ${GRPC_BUILD_DIR}/third_party/zlib/libz.a)
-
-add_library(libcrypto STATIC IMPORTED)
-set_target_properties(libcrypto PROPERTIES IMPORTED_LOCATION
- ${GRPC_BUILD_DIR}/third_party/boringssl/crypto/libcrypto.a)
-
-add_library(libssl STATIC IMPORTED)
-set_target_properties(libssl PROPERTIES IMPORTED_LOCATION
- ${GRPC_BUILD_DIR}/third_party/boringssl/ssl/libssl.a)
-
set(GRPC_PROTO_GENS_DIR ${CMAKE_BINARY_DIR}/gens)
file(MAKE_DIRECTORY ${GRPC_PROTO_GENS_DIR})
include_directories(${GRPC_PROTO_GENS_DIR})
@@ -96,8 +66,8 @@
SHARED ${HELLOWORLD_PROTO_HDRS} ${HELLOWORLD_PROTO_SRCS})
target_link_libraries(helloworld_proto_lib
+ grpc++
libprotobuf
- libgrpc++
android
log)
@@ -111,13 +81,6 @@
PRIVATE ${HELLOWORLD_PROTO_HEADERS})
target_link_libraries(grpc-helloworld
- libgrpc++
- libgrpc
- libzlib
- libcares
- libssl
- libcrypto
helloworld_proto_lib
- libgpr
android
${log-lib})
diff --git a/examples/cpp/helloworld/CMakeLists.txt b/examples/cpp/helloworld/CMakeLists.txt
index c3ce4d5..d0f705f 100644
--- a/examples/cpp/helloworld/CMakeLists.txt
+++ b/examples/cpp/helloworld/CMakeLists.txt
@@ -1,7 +1,24 @@
-# Minimum CMake required
+# Copyright 2018 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.
+#
+# cmake build file for C++ helloworld example.
+# Assumes protobuf and gRPC have been installed using cmake.
+# See cmake_externalproject/CMakeLists.txt for all-in-one cmake build
+# that automatically builds all the dependencies before building helloworld.
+
cmake_minimum_required(VERSION 2.8)
-# Project
project(HelloWorld C CXX)
if(NOT MSVC)
@@ -10,57 +27,76 @@
add_definitions(-D_WIN32_WINNT=0x600)
endif()
-# Protobuf
-# NOTE: we cannot use "CONFIG" mode here because protobuf-config.cmake
-# is broken when used with CMAKE_INSTALL_PREFIX
-find_package(Protobuf REQUIRED)
-message(STATUS "Using protobuf ${protobuf_VERSION}")
-
-# {Protobuf,PROTOBUF}_FOUND is defined based on find_package type ("MODULE" vs "CONFIG").
-# For "MODULE", the case has also changed between cmake 3.5 and 3.6.
-# We use the legacy uppercase version for *_LIBRARIES AND *_INCLUDE_DIRS variables
-# as newer cmake versions provide them too for backward compatibility.
-if(Protobuf_FOUND OR PROTOBUF_FOUND)
- if(TARGET protobuf::libprotobuf)
- set(_PROTOBUF_LIBPROTOBUF protobuf::libprotobuf)
- else()
- set(_PROTOBUF_LIBPROTOBUF ${PROTOBUF_LIBRARIES})
- include_directories(${PROTOBUF_INCLUDE_DIRS})
- endif()
- if(TARGET protobuf::protoc)
- set(_PROTOBUF_PROTOC $<TARGET_FILE:protobuf::protoc>)
- else()
- set(_PROTOBUF_PROTOC ${PROTOBUF_PROTOC_EXECUTABLE})
- endif()
+if(GRPC_AS_SUBMODULE)
+ # One way to build a projects that uses gRPC is to just include the
+ # entire gRPC project tree via "add_subdirectory".
+ # This approach is very simple to use, but the are some potential
+ # disadvantages:
+ # * it includes gRPC's CMakeLists.txt directly into your build script
+ # without and that can make gRPC's internal setting interfere with your
+ # own build.
+ # * depending on what's installed on your system, the contents of submodules
+ # in gRPC's third_party/* might need to be available (and there might be
+ # additional prerequisites required to build them). Consider using
+ # the gRPC_*_PROVIDER options to fine-tune the expected behavior.
+ #
+ # A more robust approach to add dependency on gRPC is using
+ # cmake's ExternalProject_Add (see cmake_externalproject/CMakeLists.txt).
+
+ # Include the gRPC's cmake build (normally grpc source code would live
+ # in a git submodule called "third_party/grpc", but this example lives in
+ # the same repository as gRPC sources, so we just look a few directories up)
+ add_subdirectory(../../.. ${CMAKE_CURRENT_BINARY_DIR}/grpc EXCLUDE_FROM_ALL)
+ message(STATUS "Using gRPC via add_subdirectory.")
+
+ # After using add_subdirectory, we can now use the grpc targets directly from
+ # this build.
+ set(_PROTOBUF_LIBPROTOBUF libprotobuf)
+ set(_PROTOBUF_PROTOC $<TARGET_FILE:protoc>)
+ set(_GRPC_GRPCPP_UNSECURE grpc++_unsecure)
+ set(_GRPC_CPP_PLUGIN_EXECUTABLE $<TARGET_FILE:grpc_cpp_plugin>)
else()
- message(WARNING "Failed to locate libprotobuf and protoc!")
+ # This branch assumes that gRPC and all its dependencies are already installed
+ # on this system, so they can be located by find_package().
+
+ # Find Protobuf installation
+ # Looks for protobuf-config.cmake file installed by Protobuf's cmake installation.
+ set(protobuf_MODULE_COMPATIBLE TRUE)
+ find_package(Protobuf CONFIG REQUIRED)
+ message(STATUS "Using protobuf ${protobuf_VERSION}")
+
+ set(_PROTOBUF_LIBPROTOBUF protobuf::libprotobuf)
+ set(_PROTOBUF_PROTOC $<TARGET_FILE:protobuf::protoc>)
+
+ # Find gRPC installation
+ # Looks for gRPCConfig.cmake file installed by gRPC's cmake installation.
+ find_package(gRPC CONFIG REQUIRED)
+ message(STATUS "Using gRPC ${gRPC_VERSION}")
+
+ set(_GRPC_GRPCPP_UNSECURE gRPC::grpc++_unsecure)
+ set(_GRPC_CPP_PLUGIN_EXECUTABLE $<TARGET_FILE:gRPC::grpc_cpp_plugin>)
endif()
-# gRPC
-find_package(gRPC CONFIG REQUIRED)
-message(STATUS "Using gRPC ${gRPC_VERSION}")
-
-# gRPC C++ plugin
-get_target_property(gRPC_CPP_PLUGIN_EXECUTABLE gRPC::grpc_cpp_plugin
- IMPORTED_LOCATION_RELEASE)
-
# Proto file
get_filename_component(hw_proto "../../protos/helloworld.proto" ABSOLUTE)
get_filename_component(hw_proto_path "${hw_proto}" PATH)
# Generated sources
-protobuf_generate_cpp(hw_proto_srcs hw_proto_hdrs "${hw_proto}")
+set(hw_proto_srcs "${CMAKE_CURRENT_BINARY_DIR}/helloworld.pb.cc")
+set(hw_proto_hdrs "${CMAKE_CURRENT_BINARY_DIR}/helloworld.pb.h")
set(hw_grpc_srcs "${CMAKE_CURRENT_BINARY_DIR}/helloworld.grpc.pb.cc")
set(hw_grpc_hdrs "${CMAKE_CURRENT_BINARY_DIR}/helloworld.grpc.pb.h")
add_custom_command(
- OUTPUT "${hw_grpc_srcs}" "${hw_grpc_hdrs}"
+ OUTPUT "${hw_proto_srcs}" "${hw_proto_hdrs}" "${hw_grpc_srcs}" "${hw_grpc_hdrs}"
COMMAND ${_PROTOBUF_PROTOC}
- ARGS --grpc_out "${CMAKE_CURRENT_BINARY_DIR}" -I "${hw_proto_path}"
- --plugin=protoc-gen-grpc="${gRPC_CPP_PLUGIN_EXECUTABLE}"
+ ARGS --grpc_out "${CMAKE_CURRENT_BINARY_DIR}"
+ --cpp_out "${CMAKE_CURRENT_BINARY_DIR}"
+ -I "${hw_proto_path}"
+ --plugin=protoc-gen-grpc="${_GRPC_CPP_PLUGIN_EXECUTABLE}"
"${hw_proto}"
DEPENDS "${hw_proto}")
-# Generated include directory
+# Include generated *.pb.h files
include_directories("${CMAKE_CURRENT_BINARY_DIR}")
# Targets greeter_[async_](client|server)
@@ -71,6 +107,6 @@
${hw_proto_srcs}
${hw_grpc_srcs})
target_link_libraries(${_target}
- ${_PROTOBUF_LIBPROTOBUF}
- gRPC::grpc++_unsecure)
+ ${_GRPC_GRPCPP_UNSECURE}
+ ${_PROTOBUF_LIBPROTOBUF})
endforeach()
diff --git a/examples/cpp/helloworld/cmake_externalproject/CMakeLists.txt b/examples/cpp/helloworld/cmake_externalproject/CMakeLists.txt
new file mode 100644
index 0000000..9fbdf07
--- /dev/null
+++ b/examples/cpp/helloworld/cmake_externalproject/CMakeLists.txt
@@ -0,0 +1,116 @@
+# Copyright 2018 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.
+#
+# cmake "superbuild" file for C++ helloworld example.
+# This build file demonstrates how to build the helloworld project
+# and all its dependencies in a single cmake build (hence "superbuild")
+# that is easy to build and maintain.
+# cmake's ExternalProject_Add() is used to import all the sub-projects,
+# including the "helloworld" project itself.
+# See https://blog.kitware.com/cmake-superbuilds-git-submodules/
+
+cmake_minimum_required(VERSION 2.8)
+
+# Project
+project(HelloWorld-SuperBuild C CXX)
+
+include(ExternalProject)
+
+# Builds c-ares project from the git submodule.
+# Note: For all external projects, instead of using checked-out code, one could
+# specify GIT_REPOSITORY and GIT_TAG to have cmake download the dependency directly,
+# without needing to add a submodule to your project.
+ExternalProject_Add(c-ares
+ PREFIX c-ares
+ SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../third_party/cares/cares"
+ CMAKE_CACHE_ARGS
+ -DCARES_SHARED:BOOL=OFF
+ -DCARES_STATIC:BOOL=ON
+ -DCARES_STATIC_PIC:BOOL=ON
+ -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_CURRENT_BINARY_DIR}/c-ares
+)
+
+# Builds protobuf project from the git submodule.
+ExternalProject_Add(protobuf
+ PREFIX protobuf
+ SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../third_party/protobuf/cmake"
+ CMAKE_CACHE_ARGS
+ -Dprotobuf_BUILD_TESTS:BOOL=OFF
+ -Dprotobuf_WITH_ZLIB:BOOL=OFF
+ -Dprotobuf_MSVC_STATIC_RUNTIME:BOOL=OFF
+ -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_CURRENT_BINARY_DIR}/protobuf
+)
+
+# Builds zlib project from the git submodule.
+ExternalProject_Add(zlib
+ PREFIX zlib
+ SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../third_party/zlib"
+ CMAKE_CACHE_ARGS
+ -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_CURRENT_BINARY_DIR}/zlib
+)
+
+# the location where protobuf-config.cmake will be installed varies by platform
+if (WIN32)
+ set(_FINDPACKAGE_PROTOBUF_CONFIG_DIR "${CMAKE_CURRENT_BINARY_DIR}/protobuf/cmake")
+else()
+ set(_FINDPACKAGE_PROTOBUF_CONFIG_DIR "${CMAKE_CURRENT_BINARY_DIR}/protobuf/lib/cmake/protobuf")
+endif()
+
+# if OPENSSL_ROOT_DIR is set, propagate that hint path to the external projects with OpenSSL dependency.
+set(_CMAKE_ARGS_OPENSSL_ROOT_DIR "")
+if (OPENSSL_ROOT_DIR)
+ set(_CMAKE_ARGS_OPENSSL_ROOT_DIR "-DOPENSSL_ROOT_DIR:PATH=${OPENSSL_ROOT_DIR}")
+endif()
+
+# Builds gRPC based on locally checked-out sources and set arguments so that all the dependencies
+# are correctly located.
+ExternalProject_Add(grpc
+ PREFIX grpc
+ SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../.."
+ CMAKE_CACHE_ARGS
+ -DgRPC_INSTALL:BOOL=ON
+ -DgRPC_BUILD_TESTS:BOOL=OFF
+ -DgRPC_PROTOBUF_PROVIDER:STRING=package
+ -DgRPC_PROTOBUF_PACKAGE_TYPE:STRING=CONFIG
+ -DProtobuf_DIR:PATH=${_FINDPACKAGE_PROTOBUF_CONFIG_DIR}
+ -DgRPC_ZLIB_PROVIDER:STRING=package
+ -DZLIB_ROOT:STRING=${CMAKE_CURRENT_BINARY_DIR}/zlib
+ -DgRPC_CARES_PROVIDER:STRING=package
+ -Dc-ares_DIR:PATH=${CMAKE_CURRENT_BINARY_DIR}/c-ares/lib/cmake/c-ares
+ -DgRPC_SSL_PROVIDER:STRING=package
+ ${_CMAKE_ARGS_OPENSSL_ROOT_DIR}
+ -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_CURRENT_BINARY_DIR}/grpc
+ DEPENDS c-ares protobuf zlib
+)
+
+# Build the helloworld projects itself using a CMakeLists.txt that assumes all the dependencies
+# have already been installed.
+# Even though helloworld is not really an "external project" from perspective of this build,
+# we are still importing it using ExternalProject_Add because that allows us to use find_package()
+# to locate all the dependencies (if we were building helloworld directly in this build we,
+# we would have needed to manually import the libraries as opposed to reusing targets exported by
+# gRPC and protobuf).
+ExternalProject_Add(helloworld
+ PREFIX helloworld
+ SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/.."
+ BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/helloworld"
+ INSTALL_COMMAND ""
+ CMAKE_CACHE_ARGS
+ -DProtobuf_DIR:PATH=${_FINDPACKAGE_PROTOBUF_CONFIG_DIR}
+ -Dc-ares_DIR:PATH=${CMAKE_CURRENT_BINARY_DIR}/c-ares/lib/cmake/c-ares
+ -DZLIB_ROOT:STRING=${CMAKE_CURRENT_BINARY_DIR}/zlib
+ ${_CMAKE_ARGS_OPENSSL_ROOT_DIR}
+ -DgRPC_DIR:PATH=${CMAKE_CURRENT_BINARY_DIR}/grpc/lib/cmake/grpc
+ DEPENDS protobuf grpc
+)
diff --git a/examples/csharp/helloworld-from-cli/global.json b/examples/csharp/helloworld-from-cli/global.json
deleted file mode 100644
index e4b797e..0000000
--- a/examples/csharp/helloworld-from-cli/global.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "sdk": {
- "version": "1.0.0"
- }
-}
diff --git a/examples/node/dynamic_codegen/route_guide/route_guide_server.js b/examples/node/dynamic_codegen/route_guide/route_guide_server.js
index f9028e8..3819c09 100644
--- a/examples/node/dynamic_codegen/route_guide/route_guide_server.js
+++ b/examples/node/dynamic_codegen/route_guide/route_guide_server.js
@@ -122,7 +122,7 @@
var deltalon = lon2-lon1;
var a = Math.sin(deltalat/2) * Math.sin(deltalat/2) +
Math.cos(lat1) * Math.cos(lat2) *
- Math.sin(dlon/2) * Math.sin(dlon/2);
+ Math.sin(deltalon/2) * Math.sin(deltalon/2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
return R * c;
}
diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec
index f53e9db..29b79e0 100644
--- a/gRPC-C++.podspec
+++ b/gRPC-C++.podspec
@@ -23,7 +23,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-C++'
# TODO (mxyan): use version that match gRPC version when pod is stabilized
- # version = '1.11.0-dev'
+ # version = '1.13.0-dev'
version = '0.0.2'
s.version = version
s.summary = 'gRPC C++ library'
@@ -31,7 +31,7 @@
s.license = 'Apache License, Version 2.0'
s.authors = { 'The gRPC contributors' => 'grpc-packages@google.com' }
- grpc_version = '1.11.0-dev'
+ grpc_version = '1.13.0-dev'
s.source = {
:git => 'https://github.com/grpc/grpc.git',
@@ -112,6 +112,8 @@
'include/grpcpp/support/byte_buffer.h',
'include/grpcpp/support/channel_arguments.h',
'include/grpcpp/support/config.h',
+ 'include/grpcpp/support/proto_buffer_reader.h',
+ 'include/grpcpp/support/proto_buffer_writer.h',
'include/grpcpp/support/slice.h',
'include/grpcpp/support/status.h',
'include/grpcpp/support/status_code_enum.h',
@@ -206,7 +208,6 @@
'src/cpp/server/server_posix.cc',
'src/cpp/thread_manager/thread_manager.cc',
'src/cpp/util/byte_buffer_cc.cc',
- 'src/cpp/util/slice_cc.cc',
'src/cpp/util/status.cc',
'src/cpp/util/string_ref.cc',
'src/cpp/util/time_cc.cc',
@@ -259,6 +260,7 @@
'src/core/ext/filters/http/client/http_client_filter.h',
'src/core/ext/filters/http/message_compress/message_compress_filter.h',
'src/core/ext/filters/http/server/http_server_filter.h',
+ 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h',
'src/core/lib/security/context/security_context.h',
'src/core/lib/security/credentials/alts/alts_credentials.h',
'src/core/lib/security/credentials/composite/composite_credentials.h',
@@ -306,8 +308,8 @@
'src/core/tsi/alts/handshaker/handshaker.pb.h',
'src/core/tsi/alts/handshaker/transport_security_common.pb.h',
'src/core/tsi/transport_security.h',
- 'src/core/tsi/transport_security_adapter.h',
'src/core/tsi/transport_security_interface.h',
+ 'src/core/ext/transport/chttp2/client/authority.h',
'src/core/ext/transport/chttp2/client/chttp2_connector.h',
'src/core/ext/filters/client_channel/backup_poller.h',
'src/core/ext/filters/client_channel/client_channel.h',
@@ -485,6 +487,7 @@
'src/core/ext/filters/load_reporting/server_load_reporting_plugin.h',
'src/core/ext/filters/max_age/max_age_filter.h',
'src/core/ext/filters/message_size/message_size_filter.h',
+ 'src/core/ext/filters/http/client_authority_filter.h',
'src/core/ext/filters/workarounds/workaround_cronet_compression_filter.h',
'src/core/ext/filters/workarounds/workaround_utils.h'
diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec
index f93dded..ce6ff76 100644
--- a/gRPC-Core.podspec
+++ b/gRPC-Core.podspec
@@ -22,7 +22,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-Core'
- version = '1.11.0-dev'
+ version = '1.13.0-dev'
s.version = version
s.summary = 'Core cross-platform gRPC library, written in C'
s.homepage = 'https://grpc.io'
@@ -182,6 +182,7 @@
ss.dependency 'BoringSSL', '~> 10.0'
ss.dependency 'nanopb', '~> 0.3'
+ # To save you from scrolling, this is the last part of the podspec.
ss.source_files = 'src/core/lib/gpr/arena.h',
'src/core/lib/gpr/env.h',
'src/core/lib/gpr/fork.h',
@@ -269,6 +270,7 @@
'src/core/ext/filters/http/client/http_client_filter.h',
'src/core/ext/filters/http/message_compress/message_compress_filter.h',
'src/core/ext/filters/http/server/http_server_filter.h',
+ 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h',
'src/core/lib/security/context/security_context.h',
'src/core/lib/security/credentials/alts/alts_credentials.h',
'src/core/lib/security/credentials/composite/composite_credentials.h',
@@ -316,8 +318,8 @@
'src/core/tsi/alts/handshaker/handshaker.pb.h',
'src/core/tsi/alts/handshaker/transport_security_common.pb.h',
'src/core/tsi/transport_security.h',
- 'src/core/tsi/transport_security_adapter.h',
'src/core/tsi/transport_security_interface.h',
+ 'src/core/ext/transport/chttp2/client/authority.h',
'src/core/ext/transport/chttp2/client/chttp2_connector.h',
'src/core/ext/filters/client_channel/backup_poller.h',
'src/core/ext/filters/client_channel/client_channel.h',
@@ -495,6 +497,7 @@
'src/core/ext/filters/load_reporting/server_load_reporting_plugin.h',
'src/core/ext/filters/max_age/max_age_filter.h',
'src/core/ext/filters/message_size/message_size_filter.h',
+ 'src/core/ext/filters/http/client_authority_filter.h',
'src/core/ext/filters/workarounds/workaround_cronet_compression_filter.h',
'src/core/ext/filters/workarounds/workaround_utils.h',
'src/core/lib/surface/init.cc',
@@ -733,9 +736,9 @@
'src/core/tsi/alts/handshaker/handshaker.pb.c',
'src/core/tsi/alts/handshaker/transport_security_common.pb.c',
'src/core/tsi/transport_security.cc',
- 'src/core/tsi/transport_security_adapter.cc',
'src/core/ext/transport/chttp2/client/insecure/channel_create.cc',
'src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc',
+ 'src/core/ext/transport/chttp2/client/authority.cc',
'src/core/ext/transport/chttp2/client/chttp2_connector.cc',
'src/core/ext/filters/client_channel/backup_poller.cc',
'src/core/ext/filters/client_channel/channel_connectivity.cc',
@@ -780,7 +783,6 @@
'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c',
'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc',
'src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc',
- 'src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc',
'src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc',
@@ -793,6 +795,7 @@
'src/core/ext/census/grpc_context.cc',
'src/core/ext/filters/max_age/max_age_filter.cc',
'src/core/ext/filters/message_size/message_size_filter.cc',
+ 'src/core/ext/filters/http/client_authority_filter.cc',
'src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc',
'src/core/ext/filters/workarounds/workaround_utils.cc',
'src/core/plugin_registry/grpc_plugin_registry.cc'
@@ -845,6 +848,7 @@
'src/core/ext/filters/http/client/http_client_filter.h',
'src/core/ext/filters/http/message_compress/message_compress_filter.h',
'src/core/ext/filters/http/server/http_server_filter.h',
+ 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h',
'src/core/lib/security/context/security_context.h',
'src/core/lib/security/credentials/alts/alts_credentials.h',
'src/core/lib/security/credentials/composite/composite_credentials.h',
@@ -892,8 +896,8 @@
'src/core/tsi/alts/handshaker/handshaker.pb.h',
'src/core/tsi/alts/handshaker/transport_security_common.pb.h',
'src/core/tsi/transport_security.h',
- 'src/core/tsi/transport_security_adapter.h',
'src/core/tsi/transport_security_interface.h',
+ 'src/core/ext/transport/chttp2/client/authority.h',
'src/core/ext/transport/chttp2/client/chttp2_connector.h',
'src/core/ext/filters/client_channel/backup_poller.h',
'src/core/ext/filters/client_channel/client_channel.h',
@@ -1071,960 +1075,41 @@
'src/core/ext/filters/load_reporting/server_load_reporting_plugin.h',
'src/core/ext/filters/max_age/max_age_filter.h',
'src/core/ext/filters/message_size/message_size_filter.h',
+ 'src/core/ext/filters/http/client_authority_filter.h',
'src/core/ext/filters/workarounds/workaround_cronet_compression_filter.h',
'src/core/ext/filters/workarounds/workaround_utils.h'
end
s.subspec 'Cronet-Interface' do |ss|
ss.header_mappings_dir = 'include/grpc'
- ss.source_files = 'include/grpc/support/alloc.h',
- 'include/grpc/support/atm.h',
- 'include/grpc/support/atm_gcc_atomic.h',
- 'include/grpc/support/atm_gcc_sync.h',
- 'include/grpc/support/atm_windows.h',
- 'include/grpc/support/cpu.h',
- 'include/grpc/support/log.h',
- 'include/grpc/support/log_windows.h',
- 'include/grpc/support/port_platform.h',
- 'include/grpc/support/string_util.h',
- 'include/grpc/support/sync.h',
- 'include/grpc/support/sync_custom.h',
- 'include/grpc/support/sync_generic.h',
- 'include/grpc/support/sync_posix.h',
- 'include/grpc/support/sync_windows.h',
- 'include/grpc/support/thd_id.h',
- 'include/grpc/support/time.h',
- 'include/grpc/impl/codegen/atm.h',
- 'include/grpc/impl/codegen/atm_gcc_atomic.h',
- 'include/grpc/impl/codegen/atm_gcc_sync.h',
- 'include/grpc/impl/codegen/atm_windows.h',
- 'include/grpc/impl/codegen/fork.h',
- 'include/grpc/impl/codegen/gpr_slice.h',
- 'include/grpc/impl/codegen/gpr_types.h',
- 'include/grpc/impl/codegen/port_platform.h',
- 'include/grpc/impl/codegen/sync.h',
- 'include/grpc/impl/codegen/sync_custom.h',
- 'include/grpc/impl/codegen/sync_generic.h',
- 'include/grpc/impl/codegen/sync_posix.h',
- 'include/grpc/impl/codegen/sync_windows.h',
- 'include/grpc/impl/codegen/byte_buffer.h',
- 'include/grpc/impl/codegen/byte_buffer_reader.h',
- 'include/grpc/impl/codegen/compression_types.h',
- 'include/grpc/impl/codegen/connectivity_state.h',
- 'include/grpc/impl/codegen/grpc_types.h',
- 'include/grpc/impl/codegen/propagation_bits.h',
- 'include/grpc/impl/codegen/slice.h',
- 'include/grpc/impl/codegen/status.h',
- 'include/grpc/impl/codegen/atm.h',
- 'include/grpc/impl/codegen/atm_gcc_atomic.h',
- 'include/grpc/impl/codegen/atm_gcc_sync.h',
- 'include/grpc/impl/codegen/atm_windows.h',
- 'include/grpc/impl/codegen/fork.h',
- 'include/grpc/impl/codegen/gpr_slice.h',
- 'include/grpc/impl/codegen/gpr_types.h',
- 'include/grpc/impl/codegen/port_platform.h',
- 'include/grpc/impl/codegen/sync.h',
- 'include/grpc/impl/codegen/sync_custom.h',
- 'include/grpc/impl/codegen/sync_generic.h',
- 'include/grpc/impl/codegen/sync_posix.h',
- 'include/grpc/impl/codegen/sync_windows.h',
- 'include/grpc/byte_buffer.h',
- 'include/grpc/byte_buffer_reader.h',
- 'include/grpc/compression.h',
- 'include/grpc/fork.h',
- 'include/grpc/grpc.h',
- 'include/grpc/grpc_posix.h',
- 'include/grpc/grpc_security_constants.h',
- 'include/grpc/load_reporting.h',
- 'include/grpc/slice.h',
- 'include/grpc/slice_buffer.h',
- 'include/grpc/status.h',
- 'include/grpc/support/workaround_list.h',
- 'include/grpc/grpc_cronet.h',
- 'include/grpc/grpc_security.h'
+ ss.source_files = 'include/grpc/grpc_cronet.h'
end
s.subspec 'Cronet-Implementation' do |ss|
ss.header_mappings_dir = '.'
- ss.libraries = 'z'
- ss.dependency "#{s.name}/Cronet-Interface", version
- ss.dependency 'BoringSSL', '~> 10.0'
- ss.dependency 'nanopb', '~> 0.3'
- ss.source_files = 'src/core/lib/gpr/arena.h',
- 'src/core/lib/gpr/env.h',
- 'src/core/lib/gpr/fork.h',
- 'src/core/lib/gpr/host_port.h',
- 'src/core/lib/gpr/mpscq.h',
- 'src/core/lib/gpr/murmur_hash.h',
- 'src/core/lib/gpr/spinlock.h',
- 'src/core/lib/gpr/string.h',
- 'src/core/lib/gpr/string_windows.h',
- 'src/core/lib/gpr/time_precise.h',
- 'src/core/lib/gpr/tls.h',
- 'src/core/lib/gpr/tls_gcc.h',
- 'src/core/lib/gpr/tls_msvc.h',
- 'src/core/lib/gpr/tls_pthread.h',
- 'src/core/lib/gpr/tmpfile.h',
- 'src/core/lib/gpr/useful.h',
- 'src/core/lib/gprpp/abstract.h',
- 'src/core/lib/gprpp/atomic.h',
- 'src/core/lib/gprpp/atomic_with_atm.h',
- 'src/core/lib/gprpp/atomic_with_std.h',
- 'src/core/lib/gprpp/manual_constructor.h',
- 'src/core/lib/gprpp/memory.h',
- 'src/core/lib/gprpp/thd.h',
- 'src/core/lib/profiling/timers.h',
- 'src/core/lib/gpr/alloc.cc',
- 'src/core/lib/gpr/arena.cc',
- 'src/core/lib/gpr/atm.cc',
- 'src/core/lib/gpr/cpu_iphone.cc',
- 'src/core/lib/gpr/cpu_linux.cc',
- 'src/core/lib/gpr/cpu_posix.cc',
- 'src/core/lib/gpr/cpu_windows.cc',
- 'src/core/lib/gpr/env_linux.cc',
- 'src/core/lib/gpr/env_posix.cc',
- 'src/core/lib/gpr/env_windows.cc',
- 'src/core/lib/gpr/fork.cc',
- 'src/core/lib/gpr/host_port.cc',
- 'src/core/lib/gpr/log.cc',
- 'src/core/lib/gpr/log_android.cc',
- 'src/core/lib/gpr/log_linux.cc',
- 'src/core/lib/gpr/log_posix.cc',
- 'src/core/lib/gpr/log_windows.cc',
- 'src/core/lib/gpr/mpscq.cc',
- 'src/core/lib/gpr/murmur_hash.cc',
- 'src/core/lib/gpr/string.cc',
- 'src/core/lib/gpr/string_posix.cc',
- 'src/core/lib/gpr/string_util_windows.cc',
- 'src/core/lib/gpr/string_windows.cc',
- 'src/core/lib/gpr/sync.cc',
- 'src/core/lib/gpr/sync_posix.cc',
- 'src/core/lib/gpr/sync_windows.cc',
- 'src/core/lib/gpr/time.cc',
- 'src/core/lib/gpr/time_posix.cc',
- 'src/core/lib/gpr/time_precise.cc',
- 'src/core/lib/gpr/time_windows.cc',
- 'src/core/lib/gpr/tls_pthread.cc',
- 'src/core/lib/gpr/tmpfile_msys.cc',
- 'src/core/lib/gpr/tmpfile_posix.cc',
- 'src/core/lib/gpr/tmpfile_windows.cc',
- 'src/core/lib/gpr/wrap_memcpy.cc',
- 'src/core/lib/gprpp/thd_posix.cc',
- 'src/core/lib/gprpp/thd_windows.cc',
- 'src/core/lib/profiling/basic_timers.cc',
- 'src/core/lib/profiling/stap_timers.cc',
- 'src/core/lib/avl/avl.h',
- 'src/core/lib/backoff/backoff.h',
- 'src/core/lib/channel/channel_args.h',
- 'src/core/lib/channel/channel_stack.h',
- 'src/core/lib/channel/channel_stack_builder.h',
- 'src/core/lib/channel/channel_trace.h',
- 'src/core/lib/channel/channel_trace_registry.h',
- 'src/core/lib/channel/connected_channel.h',
- 'src/core/lib/channel/context.h',
- 'src/core/lib/channel/handshaker.h',
- 'src/core/lib/channel/handshaker_factory.h',
- 'src/core/lib/channel/handshaker_registry.h',
- 'src/core/lib/channel/status_util.h',
- 'src/core/lib/compression/algorithm_metadata.h',
- 'src/core/lib/compression/compression_internal.h',
- 'src/core/lib/compression/message_compress.h',
- 'src/core/lib/compression/stream_compression.h',
- 'src/core/lib/compression/stream_compression_gzip.h',
- 'src/core/lib/compression/stream_compression_identity.h',
- 'src/core/lib/debug/stats.h',
- 'src/core/lib/debug/stats_data.h',
- 'src/core/lib/gprpp/debug_location.h',
- 'src/core/lib/gprpp/inlined_vector.h',
- 'src/core/lib/gprpp/orphanable.h',
- 'src/core/lib/gprpp/ref_counted.h',
- 'src/core/lib/gprpp/ref_counted_ptr.h',
- 'src/core/lib/http/format_request.h',
- 'src/core/lib/http/httpcli.h',
- 'src/core/lib/http/parser.h',
- 'src/core/lib/iomgr/block_annotate.h',
- 'src/core/lib/iomgr/call_combiner.h',
- 'src/core/lib/iomgr/closure.h',
- 'src/core/lib/iomgr/combiner.h',
- 'src/core/lib/iomgr/endpoint.h',
- 'src/core/lib/iomgr/endpoint_pair.h',
- 'src/core/lib/iomgr/error.h',
- 'src/core/lib/iomgr/error_internal.h',
- 'src/core/lib/iomgr/ev_epoll1_linux.h',
- 'src/core/lib/iomgr/ev_epollex_linux.h',
- 'src/core/lib/iomgr/ev_epollsig_linux.h',
- 'src/core/lib/iomgr/ev_poll_posix.h',
- 'src/core/lib/iomgr/ev_posix.h',
- 'src/core/lib/iomgr/exec_ctx.h',
- 'src/core/lib/iomgr/executor.h',
- 'src/core/lib/iomgr/gethostname.h',
- 'src/core/lib/iomgr/iocp_windows.h',
- 'src/core/lib/iomgr/iomgr.h',
- 'src/core/lib/iomgr/iomgr_custom.h',
- 'src/core/lib/iomgr/iomgr_internal.h',
- 'src/core/lib/iomgr/iomgr_posix.h',
- 'src/core/lib/iomgr/is_epollexclusive_available.h',
- 'src/core/lib/iomgr/load_file.h',
- 'src/core/lib/iomgr/lockfree_event.h',
- 'src/core/lib/iomgr/nameser.h',
- 'src/core/lib/iomgr/network_status_tracker.h',
- 'src/core/lib/iomgr/polling_entity.h',
- 'src/core/lib/iomgr/pollset.h',
- 'src/core/lib/iomgr/pollset_custom.h',
- 'src/core/lib/iomgr/pollset_set.h',
- 'src/core/lib/iomgr/pollset_set_custom.h',
- 'src/core/lib/iomgr/pollset_set_windows.h',
- 'src/core/lib/iomgr/pollset_windows.h',
- 'src/core/lib/iomgr/port.h',
- 'src/core/lib/iomgr/resolve_address.h',
- 'src/core/lib/iomgr/resolve_address_custom.h',
- 'src/core/lib/iomgr/resource_quota.h',
- 'src/core/lib/iomgr/sockaddr.h',
- 'src/core/lib/iomgr/sockaddr_custom.h',
- 'src/core/lib/iomgr/sockaddr_posix.h',
- 'src/core/lib/iomgr/sockaddr_utils.h',
- 'src/core/lib/iomgr/sockaddr_windows.h',
- 'src/core/lib/iomgr/socket_factory_posix.h',
- 'src/core/lib/iomgr/socket_mutator.h',
- 'src/core/lib/iomgr/socket_utils.h',
- 'src/core/lib/iomgr/socket_utils_posix.h',
- 'src/core/lib/iomgr/socket_windows.h',
- 'src/core/lib/iomgr/sys_epoll_wrapper.h',
- 'src/core/lib/iomgr/tcp_client.h',
- 'src/core/lib/iomgr/tcp_client_posix.h',
- 'src/core/lib/iomgr/tcp_custom.h',
- 'src/core/lib/iomgr/tcp_posix.h',
- 'src/core/lib/iomgr/tcp_server.h',
- 'src/core/lib/iomgr/tcp_server_utils_posix.h',
- 'src/core/lib/iomgr/tcp_windows.h',
- 'src/core/lib/iomgr/time_averaged_stats.h',
- 'src/core/lib/iomgr/timer.h',
- 'src/core/lib/iomgr/timer_custom.h',
- 'src/core/lib/iomgr/timer_heap.h',
- 'src/core/lib/iomgr/timer_manager.h',
- 'src/core/lib/iomgr/udp_server.h',
- 'src/core/lib/iomgr/unix_sockets_posix.h',
- 'src/core/lib/iomgr/wakeup_fd_cv.h',
- 'src/core/lib/iomgr/wakeup_fd_pipe.h',
- 'src/core/lib/iomgr/wakeup_fd_posix.h',
- 'src/core/lib/json/json.h',
- 'src/core/lib/json/json_common.h',
- 'src/core/lib/json/json_reader.h',
- 'src/core/lib/json/json_writer.h',
- 'src/core/lib/slice/b64.h',
- '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/slice/slice_weak_hash_table.h',
- 'src/core/lib/surface/api_trace.h',
- 'src/core/lib/surface/call.h',
- 'src/core/lib/surface/call_test_only.h',
- 'src/core/lib/surface/channel.h',
- 'src/core/lib/surface/channel_init.h',
- 'src/core/lib/surface/channel_stack_type.h',
- 'src/core/lib/surface/completion_queue.h',
- 'src/core/lib/surface/completion_queue_factory.h',
- 'src/core/lib/surface/event_string.h',
- 'src/core/lib/surface/init.h',
- 'src/core/lib/surface/lame_client.h',
- 'src/core/lib/surface/server.h',
- 'src/core/lib/surface/validate_metadata.h',
- 'src/core/lib/transport/bdp_estimator.h',
- 'src/core/lib/transport/byte_stream.h',
- 'src/core/lib/transport/connectivity_state.h',
- 'src/core/lib/transport/error_utils.h',
- 'src/core/lib/transport/http2_errors.h',
- 'src/core/lib/transport/metadata.h',
- 'src/core/lib/transport/metadata_batch.h',
- 'src/core/lib/transport/pid_controller.h',
- 'src/core/lib/transport/service_config.h',
- 'src/core/lib/transport/static_metadata.h',
- 'src/core/lib/transport/status_conversion.h',
- 'src/core/lib/transport/status_metadata.h',
- 'src/core/lib/transport/timeout_encoding.h',
- 'src/core/lib/transport/transport.h',
- 'src/core/lib/transport/transport_impl.h',
- 'src/core/lib/debug/trace.h',
- 'src/core/ext/filters/deadline/deadline_filter.h',
- 'src/core/ext/filters/client_channel/backup_poller.h',
- 'src/core/ext/filters/client_channel/client_channel.h',
- 'src/core/ext/filters/client_channel/client_channel_factory.h',
- 'src/core/ext/filters/client_channel/connector.h',
- 'src/core/ext/filters/client_channel/http_connect_handshaker.h',
- 'src/core/ext/filters/client_channel/http_proxy.h',
- 'src/core/ext/filters/client_channel/lb_policy.h',
- 'src/core/ext/filters/client_channel/lb_policy_factory.h',
- 'src/core/ext/filters/client_channel/lb_policy_registry.h',
- 'src/core/ext/filters/client_channel/method_params.h',
- 'src/core/ext/filters/client_channel/parse_address.h',
- 'src/core/ext/filters/client_channel/proxy_mapper.h',
- 'src/core/ext/filters/client_channel/proxy_mapper_registry.h',
- 'src/core/ext/filters/client_channel/resolver.h',
- 'src/core/ext/filters/client_channel/resolver_factory.h',
- 'src/core/ext/filters/client_channel/resolver_registry.h',
- 'src/core/ext/filters/client_channel/retry_throttle.h',
- 'src/core/ext/filters/client_channel/subchannel.h',
- 'src/core/ext/filters/client_channel/subchannel_index.h',
- 'src/core/ext/filters/client_channel/uri_parser.h',
- 'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h',
- 'src/core/ext/filters/max_age/max_age_filter.h',
- 'src/core/ext/filters/message_size/message_size_filter.h',
- 'src/core/ext/filters/load_reporting/server_load_reporting_filter.h',
- 'src/core/ext/filters/load_reporting/server_load_reporting_plugin.h',
- 'src/core/ext/transport/cronet/transport/cronet_transport.h',
- 'third_party/objective_c/Cronet/bidirectional_stream_c.h',
- 'src/core/ext/transport/chttp2/transport/bin_decoder.h',
- 'src/core/ext/transport/chttp2/transport/bin_encoder.h',
- 'src/core/ext/transport/chttp2/transport/chttp2_transport.h',
- 'src/core/ext/transport/chttp2/transport/flow_control.h',
- 'src/core/ext/transport/chttp2/transport/frame.h',
- 'src/core/ext/transport/chttp2/transport/frame_data.h',
- 'src/core/ext/transport/chttp2/transport/frame_goaway.h',
- 'src/core/ext/transport/chttp2/transport/frame_ping.h',
- 'src/core/ext/transport/chttp2/transport/frame_rst_stream.h',
- 'src/core/ext/transport/chttp2/transport/frame_settings.h',
- 'src/core/ext/transport/chttp2/transport/frame_window_update.h',
- 'src/core/ext/transport/chttp2/transport/hpack_encoder.h',
- 'src/core/ext/transport/chttp2/transport/hpack_parser.h',
- 'src/core/ext/transport/chttp2/transport/hpack_table.h',
- 'src/core/ext/transport/chttp2/transport/http2_settings.h',
- 'src/core/ext/transport/chttp2/transport/huffsyms.h',
- 'src/core/ext/transport/chttp2/transport/incoming_metadata.h',
- 'src/core/ext/transport/chttp2/transport/internal.h',
- 'src/core/ext/transport/chttp2/transport/stream_map.h',
- 'src/core/ext/transport/chttp2/transport/varint.h',
- 'src/core/ext/transport/chttp2/alpn/alpn.h',
- 'src/core/ext/filters/http/client/http_client_filter.h',
- 'src/core/ext/filters/http/message_compress/message_compress_filter.h',
- 'src/core/ext/filters/http/server/http_server_filter.h',
- 'src/core/lib/security/context/security_context.h',
- 'src/core/lib/security/credentials/alts/alts_credentials.h',
- 'src/core/lib/security/credentials/composite/composite_credentials.h',
- 'src/core/lib/security/credentials/credentials.h',
- 'src/core/lib/security/credentials/fake/fake_credentials.h',
- 'src/core/lib/security/credentials/google_default/google_default_credentials.h',
- 'src/core/lib/security/credentials/iam/iam_credentials.h',
- 'src/core/lib/security/credentials/jwt/json_token.h',
- 'src/core/lib/security/credentials/jwt/jwt_credentials.h',
- 'src/core/lib/security/credentials/jwt/jwt_verifier.h',
- 'src/core/lib/security/credentials/oauth2/oauth2_credentials.h',
- 'src/core/lib/security/credentials/plugin/plugin_credentials.h',
- 'src/core/lib/security/credentials/ssl/ssl_credentials.h',
- 'src/core/lib/security/security_connector/alts_security_connector.h',
- 'src/core/lib/security/security_connector/security_connector.h',
- 'src/core/lib/security/transport/auth_filters.h',
- 'src/core/lib/security/transport/secure_endpoint.h',
- 'src/core/lib/security/transport/security_handshaker.h',
- 'src/core/lib/security/transport/target_authority_table.h',
- 'src/core/lib/security/transport/tsi_error.h',
- 'src/core/lib/security/util/json_util.h',
- 'src/core/tsi/alts/crypt/gsec.h',
- 'src/core/tsi/alts/frame_protector/alts_counter.h',
- 'src/core/tsi/alts/frame_protector/alts_crypter.h',
- 'src/core/tsi/alts/frame_protector/alts_frame_protector.h',
- 'src/core/tsi/alts/frame_protector/alts_record_protocol_crypter_common.h',
- 'src/core/tsi/alts/frame_protector/frame_handler.h',
- 'src/core/tsi/alts/handshaker/alts_handshaker_client.h',
- 'src/core/tsi/alts/handshaker/alts_tsi_event.h',
- 'src/core/tsi/alts/handshaker/alts_tsi_handshaker.h',
- 'src/core/tsi/alts/handshaker/alts_tsi_handshaker_private.h',
- 'src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.h',
- 'src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.h',
- 'src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol.h',
- 'src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.h',
- 'src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.h',
- 'src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.h',
- 'src/core/lib/security/credentials/alts/check_gcp_environment.h',
- 'src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h',
- 'src/core/tsi/alts/handshaker/alts_handshaker_service_api.h',
- 'src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.h',
- 'src/core/tsi/alts/handshaker/alts_tsi_utils.h',
- 'src/core/tsi/alts/handshaker/transport_security_common_api.h',
- 'src/core/tsi/alts/handshaker/altscontext.pb.h',
- 'src/core/tsi/alts/handshaker/handshaker.pb.h',
- 'src/core/tsi/alts/handshaker/transport_security_common.pb.h',
- 'third_party/nanopb/pb.h',
- 'third_party/nanopb/pb_common.h',
- 'third_party/nanopb/pb_decode.h',
- 'third_party/nanopb/pb_encode.h',
- 'src/core/tsi/transport_security.h',
- 'src/core/tsi/transport_security_adapter.h',
- 'src/core/tsi/transport_security_interface.h',
- 'src/core/ext/transport/chttp2/client/chttp2_connector.h',
- 'src/core/tsi/alts_transport_security.h',
- 'src/core/tsi/fake_transport_security.h',
- 'src/core/tsi/ssl/session_cache/ssl_session.h',
- 'src/core/tsi/ssl/session_cache/ssl_session_cache.h',
- 'src/core/tsi/ssl_transport_security.h',
- 'src/core/tsi/ssl_types.h',
- 'src/core/tsi/transport_security_grpc.h',
- 'src/core/ext/transport/chttp2/server/chttp2_server.h',
- 'src/core/lib/surface/init.cc',
- 'src/core/lib/avl/avl.cc',
- 'src/core/lib/backoff/backoff.cc',
- 'src/core/lib/channel/channel_args.cc',
- 'src/core/lib/channel/channel_stack.cc',
- 'src/core/lib/channel/channel_stack_builder.cc',
- 'src/core/lib/channel/channel_trace.cc',
- 'src/core/lib/channel/channel_trace_registry.cc',
- 'src/core/lib/channel/connected_channel.cc',
- 'src/core/lib/channel/handshaker.cc',
- 'src/core/lib/channel/handshaker_factory.cc',
- 'src/core/lib/channel/handshaker_registry.cc',
- 'src/core/lib/channel/status_util.cc',
- 'src/core/lib/compression/compression.cc',
- 'src/core/lib/compression/compression_internal.cc',
- 'src/core/lib/compression/message_compress.cc',
- 'src/core/lib/compression/stream_compression.cc',
- 'src/core/lib/compression/stream_compression_gzip.cc',
- 'src/core/lib/compression/stream_compression_identity.cc',
- 'src/core/lib/debug/stats.cc',
- 'src/core/lib/debug/stats_data.cc',
- 'src/core/lib/http/format_request.cc',
- 'src/core/lib/http/httpcli.cc',
- 'src/core/lib/http/parser.cc',
- 'src/core/lib/iomgr/call_combiner.cc',
- 'src/core/lib/iomgr/combiner.cc',
- 'src/core/lib/iomgr/endpoint.cc',
- 'src/core/lib/iomgr/endpoint_pair_posix.cc',
- 'src/core/lib/iomgr/endpoint_pair_uv.cc',
- 'src/core/lib/iomgr/endpoint_pair_windows.cc',
- 'src/core/lib/iomgr/error.cc',
- 'src/core/lib/iomgr/ev_epoll1_linux.cc',
- 'src/core/lib/iomgr/ev_epollex_linux.cc',
- 'src/core/lib/iomgr/ev_epollsig_linux.cc',
- 'src/core/lib/iomgr/ev_poll_posix.cc',
- 'src/core/lib/iomgr/ev_posix.cc',
- 'src/core/lib/iomgr/ev_windows.cc',
- 'src/core/lib/iomgr/exec_ctx.cc',
- 'src/core/lib/iomgr/executor.cc',
- 'src/core/lib/iomgr/fork_posix.cc',
- 'src/core/lib/iomgr/fork_windows.cc',
- 'src/core/lib/iomgr/gethostname_fallback.cc',
- 'src/core/lib/iomgr/gethostname_host_name_max.cc',
- 'src/core/lib/iomgr/gethostname_sysconf.cc',
- 'src/core/lib/iomgr/iocp_windows.cc',
- 'src/core/lib/iomgr/iomgr.cc',
- 'src/core/lib/iomgr/iomgr_custom.cc',
- 'src/core/lib/iomgr/iomgr_internal.cc',
- 'src/core/lib/iomgr/iomgr_posix.cc',
- 'src/core/lib/iomgr/iomgr_uv.cc',
- 'src/core/lib/iomgr/iomgr_windows.cc',
- 'src/core/lib/iomgr/is_epollexclusive_available.cc',
- 'src/core/lib/iomgr/load_file.cc',
- 'src/core/lib/iomgr/lockfree_event.cc',
- 'src/core/lib/iomgr/network_status_tracker.cc',
- 'src/core/lib/iomgr/polling_entity.cc',
- 'src/core/lib/iomgr/pollset.cc',
- 'src/core/lib/iomgr/pollset_custom.cc',
- 'src/core/lib/iomgr/pollset_set.cc',
- 'src/core/lib/iomgr/pollset_set_custom.cc',
- 'src/core/lib/iomgr/pollset_set_windows.cc',
- 'src/core/lib/iomgr/pollset_uv.cc',
- 'src/core/lib/iomgr/pollset_windows.cc',
- 'src/core/lib/iomgr/resolve_address.cc',
- 'src/core/lib/iomgr/resolve_address_custom.cc',
- 'src/core/lib/iomgr/resolve_address_posix.cc',
- 'src/core/lib/iomgr/resolve_address_windows.cc',
- 'src/core/lib/iomgr/resource_quota.cc',
- 'src/core/lib/iomgr/sockaddr_utils.cc',
- 'src/core/lib/iomgr/socket_factory_posix.cc',
- 'src/core/lib/iomgr/socket_mutator.cc',
- 'src/core/lib/iomgr/socket_utils_common_posix.cc',
- 'src/core/lib/iomgr/socket_utils_linux.cc',
- 'src/core/lib/iomgr/socket_utils_posix.cc',
- 'src/core/lib/iomgr/socket_utils_uv.cc',
- 'src/core/lib/iomgr/socket_utils_windows.cc',
- 'src/core/lib/iomgr/socket_windows.cc',
- 'src/core/lib/iomgr/tcp_client.cc',
- 'src/core/lib/iomgr/tcp_client_custom.cc',
- 'src/core/lib/iomgr/tcp_client_posix.cc',
- 'src/core/lib/iomgr/tcp_client_windows.cc',
- 'src/core/lib/iomgr/tcp_custom.cc',
- 'src/core/lib/iomgr/tcp_posix.cc',
- 'src/core/lib/iomgr/tcp_server.cc',
- 'src/core/lib/iomgr/tcp_server_custom.cc',
- 'src/core/lib/iomgr/tcp_server_posix.cc',
- 'src/core/lib/iomgr/tcp_server_utils_posix_common.cc',
- 'src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.cc',
- 'src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.cc',
- 'src/core/lib/iomgr/tcp_server_windows.cc',
- 'src/core/lib/iomgr/tcp_uv.cc',
- 'src/core/lib/iomgr/tcp_windows.cc',
- 'src/core/lib/iomgr/time_averaged_stats.cc',
- 'src/core/lib/iomgr/timer.cc',
- 'src/core/lib/iomgr/timer_custom.cc',
- 'src/core/lib/iomgr/timer_generic.cc',
- 'src/core/lib/iomgr/timer_heap.cc',
- 'src/core/lib/iomgr/timer_manager.cc',
- 'src/core/lib/iomgr/timer_uv.cc',
- 'src/core/lib/iomgr/udp_server.cc',
- 'src/core/lib/iomgr/unix_sockets_posix.cc',
- 'src/core/lib/iomgr/unix_sockets_posix_noop.cc',
- 'src/core/lib/iomgr/wakeup_fd_cv.cc',
- 'src/core/lib/iomgr/wakeup_fd_eventfd.cc',
- 'src/core/lib/iomgr/wakeup_fd_nospecial.cc',
- 'src/core/lib/iomgr/wakeup_fd_pipe.cc',
- 'src/core/lib/iomgr/wakeup_fd_posix.cc',
- 'src/core/lib/json/json.cc',
- 'src/core/lib/json/json_reader.cc',
- 'src/core/lib/json/json_string.cc',
- 'src/core/lib/json/json_writer.cc',
- 'src/core/lib/slice/b64.cc',
- 'src/core/lib/slice/percent_encoding.cc',
- 'src/core/lib/slice/slice.cc',
- 'src/core/lib/slice/slice_buffer.cc',
- 'src/core/lib/slice/slice_intern.cc',
- 'src/core/lib/slice/slice_string_helpers.cc',
- 'src/core/lib/surface/api_trace.cc',
- 'src/core/lib/surface/byte_buffer.cc',
- 'src/core/lib/surface/byte_buffer_reader.cc',
- 'src/core/lib/surface/call.cc',
- 'src/core/lib/surface/call_details.cc',
- 'src/core/lib/surface/call_log_batch.cc',
- 'src/core/lib/surface/channel.cc',
- 'src/core/lib/surface/channel_init.cc',
- 'src/core/lib/surface/channel_ping.cc',
- 'src/core/lib/surface/channel_stack_type.cc',
- 'src/core/lib/surface/completion_queue.cc',
- 'src/core/lib/surface/completion_queue_factory.cc',
- 'src/core/lib/surface/event_string.cc',
- 'src/core/lib/surface/lame_client.cc',
- 'src/core/lib/surface/metadata_array.cc',
- 'src/core/lib/surface/server.cc',
- 'src/core/lib/surface/validate_metadata.cc',
- 'src/core/lib/surface/version.cc',
- 'src/core/lib/transport/bdp_estimator.cc',
- 'src/core/lib/transport/byte_stream.cc',
- 'src/core/lib/transport/connectivity_state.cc',
- 'src/core/lib/transport/error_utils.cc',
- 'src/core/lib/transport/metadata.cc',
- 'src/core/lib/transport/metadata_batch.cc',
- 'src/core/lib/transport/pid_controller.cc',
- 'src/core/lib/transport/service_config.cc',
- 'src/core/lib/transport/static_metadata.cc',
- 'src/core/lib/transport/status_conversion.cc',
- 'src/core/lib/transport/status_metadata.cc',
- 'src/core/lib/transport/timeout_encoding.cc',
- 'src/core/lib/transport/transport.cc',
- 'src/core/lib/transport/transport_op_string.cc',
- 'src/core/lib/debug/trace.cc',
- 'src/core/ext/filters/deadline/deadline_filter.cc',
- 'src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc',
- 'src/core/ext/filters/client_channel/backup_poller.cc',
- 'src/core/ext/filters/client_channel/channel_connectivity.cc',
- 'src/core/ext/filters/client_channel/client_channel.cc',
- 'src/core/ext/filters/client_channel/client_channel_factory.cc',
- 'src/core/ext/filters/client_channel/client_channel_plugin.cc',
- 'src/core/ext/filters/client_channel/connector.cc',
- 'src/core/ext/filters/client_channel/http_connect_handshaker.cc',
- 'src/core/ext/filters/client_channel/http_proxy.cc',
- 'src/core/ext/filters/client_channel/lb_policy.cc',
- 'src/core/ext/filters/client_channel/lb_policy_factory.cc',
- 'src/core/ext/filters/client_channel/lb_policy_registry.cc',
- 'src/core/ext/filters/client_channel/method_params.cc',
- 'src/core/ext/filters/client_channel/parse_address.cc',
- 'src/core/ext/filters/client_channel/proxy_mapper.cc',
- 'src/core/ext/filters/client_channel/proxy_mapper_registry.cc',
- 'src/core/ext/filters/client_channel/resolver.cc',
- 'src/core/ext/filters/client_channel/resolver_registry.cc',
- 'src/core/ext/filters/client_channel/retry_throttle.cc',
- 'src/core/ext/filters/client_channel/subchannel.cc',
- 'src/core/ext/filters/client_channel/subchannel_index.cc',
- 'src/core/ext/filters/client_channel/uri_parser.cc',
- 'src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc',
- 'src/core/ext/filters/max_age/max_age_filter.cc',
- 'src/core/ext/filters/message_size/message_size_filter.cc',
- 'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc',
- 'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc',
- 'src/core/ext/filters/load_reporting/server_load_reporting_filter.cc',
- 'src/core/ext/filters/load_reporting/server_load_reporting_plugin.cc',
- 'src/core/ext/transport/cronet/client/secure/cronet_channel_create.cc',
+ ss.dependency "#{s.name}/Interface", version
+ ss.dependency "#{s.name}/Implementation", version
+ ss.dependency "#{s.name}/Cronet-Interface", version
+
+ ss.source_files = 'src/core/ext/transport/cronet/client/secure/cronet_channel_create.cc',
'src/core/ext/transport/cronet/transport/cronet_transport.cc',
- 'src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc',
- 'src/core/ext/transport/chttp2/transport/bin_decoder.cc',
- 'src/core/ext/transport/chttp2/transport/bin_encoder.cc',
- 'src/core/ext/transport/chttp2/transport/chttp2_plugin.cc',
- 'src/core/ext/transport/chttp2/transport/chttp2_transport.cc',
- 'src/core/ext/transport/chttp2/transport/flow_control.cc',
- 'src/core/ext/transport/chttp2/transport/frame_data.cc',
- 'src/core/ext/transport/chttp2/transport/frame_goaway.cc',
- 'src/core/ext/transport/chttp2/transport/frame_ping.cc',
- 'src/core/ext/transport/chttp2/transport/frame_rst_stream.cc',
- 'src/core/ext/transport/chttp2/transport/frame_settings.cc',
- 'src/core/ext/transport/chttp2/transport/frame_window_update.cc',
- 'src/core/ext/transport/chttp2/transport/hpack_encoder.cc',
- 'src/core/ext/transport/chttp2/transport/hpack_parser.cc',
- 'src/core/ext/transport/chttp2/transport/hpack_table.cc',
- 'src/core/ext/transport/chttp2/transport/http2_settings.cc',
- 'src/core/ext/transport/chttp2/transport/huffsyms.cc',
- 'src/core/ext/transport/chttp2/transport/incoming_metadata.cc',
- 'src/core/ext/transport/chttp2/transport/parsing.cc',
- 'src/core/ext/transport/chttp2/transport/stream_lists.cc',
- 'src/core/ext/transport/chttp2/transport/stream_map.cc',
- 'src/core/ext/transport/chttp2/transport/varint.cc',
- 'src/core/ext/transport/chttp2/transport/writing.cc',
- 'src/core/ext/transport/chttp2/alpn/alpn.cc',
- 'src/core/ext/filters/http/client/http_client_filter.cc',
- 'src/core/ext/filters/http/http_filters_plugin.cc',
- 'src/core/ext/filters/http/message_compress/message_compress_filter.cc',
- 'src/core/ext/filters/http/server/http_server_filter.cc',
- 'src/core/lib/http/httpcli_security_connector.cc',
- 'src/core/lib/security/context/security_context.cc',
- 'src/core/lib/security/credentials/alts/alts_credentials.cc',
- 'src/core/lib/security/credentials/composite/composite_credentials.cc',
- 'src/core/lib/security/credentials/credentials.cc',
- 'src/core/lib/security/credentials/credentials_metadata.cc',
- 'src/core/lib/security/credentials/fake/fake_credentials.cc',
- 'src/core/lib/security/credentials/google_default/credentials_generic.cc',
- 'src/core/lib/security/credentials/google_default/google_default_credentials.cc',
- 'src/core/lib/security/credentials/iam/iam_credentials.cc',
- 'src/core/lib/security/credentials/jwt/json_token.cc',
- 'src/core/lib/security/credentials/jwt/jwt_credentials.cc',
- 'src/core/lib/security/credentials/jwt/jwt_verifier.cc',
- 'src/core/lib/security/credentials/oauth2/oauth2_credentials.cc',
- 'src/core/lib/security/credentials/plugin/plugin_credentials.cc',
- 'src/core/lib/security/credentials/ssl/ssl_credentials.cc',
- 'src/core/lib/security/security_connector/alts_security_connector.cc',
- 'src/core/lib/security/security_connector/security_connector.cc',
- 'src/core/lib/security/transport/client_auth_filter.cc',
- 'src/core/lib/security/transport/secure_endpoint.cc',
- 'src/core/lib/security/transport/security_handshaker.cc',
- 'src/core/lib/security/transport/server_auth_filter.cc',
- 'src/core/lib/security/transport/target_authority_table.cc',
- 'src/core/lib/security/transport/tsi_error.cc',
- 'src/core/lib/security/util/json_util.cc',
- 'src/core/lib/surface/init_secure.cc',
- 'src/core/tsi/alts/crypt/aes_gcm.cc',
- 'src/core/tsi/alts/crypt/gsec.cc',
- 'src/core/tsi/alts/frame_protector/alts_counter.cc',
- 'src/core/tsi/alts/frame_protector/alts_crypter.cc',
- 'src/core/tsi/alts/frame_protector/alts_frame_protector.cc',
- 'src/core/tsi/alts/frame_protector/alts_record_protocol_crypter_common.cc',
- 'src/core/tsi/alts/frame_protector/alts_seal_privacy_integrity_crypter.cc',
- 'src/core/tsi/alts/frame_protector/alts_unseal_privacy_integrity_crypter.cc',
- 'src/core/tsi/alts/frame_protector/frame_handler.cc',
- 'src/core/tsi/alts/handshaker/alts_handshaker_client.cc',
- 'src/core/tsi/alts/handshaker/alts_tsi_event.cc',
- 'src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc',
- 'src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc',
- 'src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.cc',
- 'src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.cc',
- 'src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.cc',
- 'src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc',
- 'src/core/lib/security/credentials/alts/check_gcp_environment.cc',
- 'src/core/lib/security/credentials/alts/check_gcp_environment_linux.cc',
- 'src/core/lib/security/credentials/alts/check_gcp_environment_no_op.cc',
- 'src/core/lib/security/credentials/alts/check_gcp_environment_windows.cc',
- 'src/core/lib/security/credentials/alts/grpc_alts_credentials_client_options.cc',
- 'src/core/lib/security/credentials/alts/grpc_alts_credentials_options.cc',
- 'src/core/lib/security/credentials/alts/grpc_alts_credentials_server_options.cc',
- 'src/core/tsi/alts/handshaker/alts_handshaker_service_api.cc',
- 'src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.cc',
- 'src/core/tsi/alts/handshaker/alts_tsi_utils.cc',
- 'src/core/tsi/alts/handshaker/transport_security_common_api.cc',
- 'src/core/tsi/alts/handshaker/altscontext.pb.c',
- 'src/core/tsi/alts/handshaker/handshaker.pb.c',
- 'src/core/tsi/alts/handshaker/transport_security_common.pb.c',
'third_party/nanopb/pb_common.c',
'third_party/nanopb/pb_decode.c',
'third_party/nanopb/pb_encode.c',
- 'src/core/tsi/transport_security.cc',
- 'src/core/tsi/transport_security_adapter.cc',
- 'src/core/ext/transport/chttp2/client/insecure/channel_create.cc',
- 'src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc',
- 'src/core/ext/transport/chttp2/client/chttp2_connector.cc',
- 'src/core/tsi/alts_transport_security.cc',
- 'src/core/tsi/fake_transport_security.cc',
- 'src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc',
- 'src/core/tsi/ssl/session_cache/ssl_session_cache.cc',
- 'src/core/tsi/ssl/session_cache/ssl_session_openssl.cc',
- 'src/core/tsi/ssl_transport_security.cc',
- 'src/core/tsi/transport_security_grpc.cc',
- 'src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc',
- 'src/core/ext/transport/chttp2/server/chttp2_server.cc',
- 'src/core/plugin_registry/grpc_cronet_plugin_registry.cc'
-
- ss.private_header_files = 'src/core/lib/gpr/arena.h',
- 'src/core/lib/gpr/env.h',
- 'src/core/lib/gpr/fork.h',
- 'src/core/lib/gpr/host_port.h',
- 'src/core/lib/gpr/mpscq.h',
- 'src/core/lib/gpr/murmur_hash.h',
- 'src/core/lib/gpr/spinlock.h',
- 'src/core/lib/gpr/string.h',
- 'src/core/lib/gpr/string_windows.h',
- 'src/core/lib/gpr/time_precise.h',
- 'src/core/lib/gpr/tls.h',
- 'src/core/lib/gpr/tls_gcc.h',
- 'src/core/lib/gpr/tls_msvc.h',
- 'src/core/lib/gpr/tls_pthread.h',
- 'src/core/lib/gpr/tmpfile.h',
- 'src/core/lib/gpr/useful.h',
- 'src/core/lib/gprpp/abstract.h',
- 'src/core/lib/gprpp/atomic.h',
- 'src/core/lib/gprpp/atomic_with_atm.h',
- 'src/core/lib/gprpp/atomic_with_std.h',
- 'src/core/lib/gprpp/manual_constructor.h',
- 'src/core/lib/gprpp/memory.h',
- 'src/core/lib/gprpp/thd.h',
- 'src/core/lib/profiling/timers.h',
- 'src/core/lib/avl/avl.h',
- 'src/core/lib/backoff/backoff.h',
- 'src/core/lib/channel/channel_args.h',
- 'src/core/lib/channel/channel_stack.h',
- 'src/core/lib/channel/channel_stack_builder.h',
- 'src/core/lib/channel/channel_trace.h',
- 'src/core/lib/channel/channel_trace_registry.h',
- 'src/core/lib/channel/connected_channel.h',
- 'src/core/lib/channel/context.h',
- 'src/core/lib/channel/handshaker.h',
- 'src/core/lib/channel/handshaker_factory.h',
- 'src/core/lib/channel/handshaker_registry.h',
- 'src/core/lib/channel/status_util.h',
- 'src/core/lib/compression/algorithm_metadata.h',
- 'src/core/lib/compression/compression_internal.h',
- 'src/core/lib/compression/message_compress.h',
- 'src/core/lib/compression/stream_compression.h',
- 'src/core/lib/compression/stream_compression_gzip.h',
- 'src/core/lib/compression/stream_compression_identity.h',
- 'src/core/lib/debug/stats.h',
- 'src/core/lib/debug/stats_data.h',
- 'src/core/lib/gprpp/debug_location.h',
- 'src/core/lib/gprpp/inlined_vector.h',
- 'src/core/lib/gprpp/orphanable.h',
- 'src/core/lib/gprpp/ref_counted.h',
- 'src/core/lib/gprpp/ref_counted_ptr.h',
- 'src/core/lib/http/format_request.h',
- 'src/core/lib/http/httpcli.h',
- 'src/core/lib/http/parser.h',
- 'src/core/lib/iomgr/block_annotate.h',
- 'src/core/lib/iomgr/call_combiner.h',
- 'src/core/lib/iomgr/closure.h',
- 'src/core/lib/iomgr/combiner.h',
- 'src/core/lib/iomgr/endpoint.h',
- 'src/core/lib/iomgr/endpoint_pair.h',
- 'src/core/lib/iomgr/error.h',
- 'src/core/lib/iomgr/error_internal.h',
- 'src/core/lib/iomgr/ev_epoll1_linux.h',
- 'src/core/lib/iomgr/ev_epollex_linux.h',
- 'src/core/lib/iomgr/ev_epollsig_linux.h',
- 'src/core/lib/iomgr/ev_poll_posix.h',
- 'src/core/lib/iomgr/ev_posix.h',
- 'src/core/lib/iomgr/exec_ctx.h',
- 'src/core/lib/iomgr/executor.h',
- 'src/core/lib/iomgr/gethostname.h',
- 'src/core/lib/iomgr/iocp_windows.h',
- 'src/core/lib/iomgr/iomgr.h',
- 'src/core/lib/iomgr/iomgr_custom.h',
- 'src/core/lib/iomgr/iomgr_internal.h',
- 'src/core/lib/iomgr/iomgr_posix.h',
- 'src/core/lib/iomgr/is_epollexclusive_available.h',
- 'src/core/lib/iomgr/load_file.h',
- 'src/core/lib/iomgr/lockfree_event.h',
- 'src/core/lib/iomgr/nameser.h',
- 'src/core/lib/iomgr/network_status_tracker.h',
- 'src/core/lib/iomgr/polling_entity.h',
- 'src/core/lib/iomgr/pollset.h',
- 'src/core/lib/iomgr/pollset_custom.h',
- 'src/core/lib/iomgr/pollset_set.h',
- 'src/core/lib/iomgr/pollset_set_custom.h',
- 'src/core/lib/iomgr/pollset_set_windows.h',
- 'src/core/lib/iomgr/pollset_windows.h',
- 'src/core/lib/iomgr/port.h',
- 'src/core/lib/iomgr/resolve_address.h',
- 'src/core/lib/iomgr/resolve_address_custom.h',
- 'src/core/lib/iomgr/resource_quota.h',
- 'src/core/lib/iomgr/sockaddr.h',
- 'src/core/lib/iomgr/sockaddr_custom.h',
- 'src/core/lib/iomgr/sockaddr_posix.h',
- 'src/core/lib/iomgr/sockaddr_utils.h',
- 'src/core/lib/iomgr/sockaddr_windows.h',
- 'src/core/lib/iomgr/socket_factory_posix.h',
- 'src/core/lib/iomgr/socket_mutator.h',
- 'src/core/lib/iomgr/socket_utils.h',
- 'src/core/lib/iomgr/socket_utils_posix.h',
- 'src/core/lib/iomgr/socket_windows.h',
- 'src/core/lib/iomgr/sys_epoll_wrapper.h',
- 'src/core/lib/iomgr/tcp_client.h',
- 'src/core/lib/iomgr/tcp_client_posix.h',
- 'src/core/lib/iomgr/tcp_custom.h',
- 'src/core/lib/iomgr/tcp_posix.h',
- 'src/core/lib/iomgr/tcp_server.h',
- 'src/core/lib/iomgr/tcp_server_utils_posix.h',
- 'src/core/lib/iomgr/tcp_windows.h',
- 'src/core/lib/iomgr/time_averaged_stats.h',
- 'src/core/lib/iomgr/timer.h',
- 'src/core/lib/iomgr/timer_custom.h',
- 'src/core/lib/iomgr/timer_heap.h',
- 'src/core/lib/iomgr/timer_manager.h',
- 'src/core/lib/iomgr/udp_server.h',
- 'src/core/lib/iomgr/unix_sockets_posix.h',
- 'src/core/lib/iomgr/wakeup_fd_cv.h',
- 'src/core/lib/iomgr/wakeup_fd_pipe.h',
- 'src/core/lib/iomgr/wakeup_fd_posix.h',
- 'src/core/lib/json/json.h',
- 'src/core/lib/json/json_common.h',
- 'src/core/lib/json/json_reader.h',
- 'src/core/lib/json/json_writer.h',
- 'src/core/lib/slice/b64.h',
- '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/slice/slice_weak_hash_table.h',
- 'src/core/lib/surface/api_trace.h',
- 'src/core/lib/surface/call.h',
- 'src/core/lib/surface/call_test_only.h',
- 'src/core/lib/surface/channel.h',
- 'src/core/lib/surface/channel_init.h',
- 'src/core/lib/surface/channel_stack_type.h',
- 'src/core/lib/surface/completion_queue.h',
- 'src/core/lib/surface/completion_queue_factory.h',
- 'src/core/lib/surface/event_string.h',
- 'src/core/lib/surface/init.h',
- 'src/core/lib/surface/lame_client.h',
- 'src/core/lib/surface/server.h',
- 'src/core/lib/surface/validate_metadata.h',
- 'src/core/lib/transport/bdp_estimator.h',
- 'src/core/lib/transport/byte_stream.h',
- 'src/core/lib/transport/connectivity_state.h',
- 'src/core/lib/transport/error_utils.h',
- 'src/core/lib/transport/http2_errors.h',
- 'src/core/lib/transport/metadata.h',
- 'src/core/lib/transport/metadata_batch.h',
- 'src/core/lib/transport/pid_controller.h',
- 'src/core/lib/transport/service_config.h',
- 'src/core/lib/transport/static_metadata.h',
- 'src/core/lib/transport/status_conversion.h',
- 'src/core/lib/transport/status_metadata.h',
- 'src/core/lib/transport/timeout_encoding.h',
- 'src/core/lib/transport/transport.h',
- 'src/core/lib/transport/transport_impl.h',
- 'src/core/lib/debug/trace.h',
- 'src/core/ext/filters/deadline/deadline_filter.h',
- 'src/core/ext/filters/client_channel/backup_poller.h',
- 'src/core/ext/filters/client_channel/client_channel.h',
- 'src/core/ext/filters/client_channel/client_channel_factory.h',
- 'src/core/ext/filters/client_channel/connector.h',
- 'src/core/ext/filters/client_channel/http_connect_handshaker.h',
- 'src/core/ext/filters/client_channel/http_proxy.h',
- 'src/core/ext/filters/client_channel/lb_policy.h',
- 'src/core/ext/filters/client_channel/lb_policy_factory.h',
- 'src/core/ext/filters/client_channel/lb_policy_registry.h',
- 'src/core/ext/filters/client_channel/method_params.h',
- 'src/core/ext/filters/client_channel/parse_address.h',
- 'src/core/ext/filters/client_channel/proxy_mapper.h',
- 'src/core/ext/filters/client_channel/proxy_mapper_registry.h',
- 'src/core/ext/filters/client_channel/resolver.h',
- 'src/core/ext/filters/client_channel/resolver_factory.h',
- 'src/core/ext/filters/client_channel/resolver_registry.h',
- 'src/core/ext/filters/client_channel/retry_throttle.h',
- 'src/core/ext/filters/client_channel/subchannel.h',
- 'src/core/ext/filters/client_channel/subchannel_index.h',
- 'src/core/ext/filters/client_channel/uri_parser.h',
- 'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h',
- 'src/core/ext/filters/max_age/max_age_filter.h',
- 'src/core/ext/filters/message_size/message_size_filter.h',
- 'src/core/ext/filters/load_reporting/server_load_reporting_filter.h',
- 'src/core/ext/filters/load_reporting/server_load_reporting_plugin.h',
- 'src/core/ext/transport/cronet/transport/cronet_transport.h',
- 'third_party/objective_c/Cronet/bidirectional_stream_c.h',
- 'src/core/ext/transport/chttp2/transport/bin_decoder.h',
- 'src/core/ext/transport/chttp2/transport/bin_encoder.h',
- 'src/core/ext/transport/chttp2/transport/chttp2_transport.h',
- 'src/core/ext/transport/chttp2/transport/flow_control.h',
- 'src/core/ext/transport/chttp2/transport/frame.h',
- 'src/core/ext/transport/chttp2/transport/frame_data.h',
- 'src/core/ext/transport/chttp2/transport/frame_goaway.h',
- 'src/core/ext/transport/chttp2/transport/frame_ping.h',
- 'src/core/ext/transport/chttp2/transport/frame_rst_stream.h',
- 'src/core/ext/transport/chttp2/transport/frame_settings.h',
- 'src/core/ext/transport/chttp2/transport/frame_window_update.h',
- 'src/core/ext/transport/chttp2/transport/hpack_encoder.h',
- 'src/core/ext/transport/chttp2/transport/hpack_parser.h',
- 'src/core/ext/transport/chttp2/transport/hpack_table.h',
- 'src/core/ext/transport/chttp2/transport/http2_settings.h',
- 'src/core/ext/transport/chttp2/transport/huffsyms.h',
- 'src/core/ext/transport/chttp2/transport/incoming_metadata.h',
- 'src/core/ext/transport/chttp2/transport/internal.h',
- 'src/core/ext/transport/chttp2/transport/stream_map.h',
- 'src/core/ext/transport/chttp2/transport/varint.h',
- 'src/core/ext/transport/chttp2/alpn/alpn.h',
- 'src/core/ext/filters/http/client/http_client_filter.h',
- 'src/core/ext/filters/http/message_compress/message_compress_filter.h',
- 'src/core/ext/filters/http/server/http_server_filter.h',
- 'src/core/lib/security/context/security_context.h',
- 'src/core/lib/security/credentials/alts/alts_credentials.h',
- 'src/core/lib/security/credentials/composite/composite_credentials.h',
- 'src/core/lib/security/credentials/credentials.h',
- 'src/core/lib/security/credentials/fake/fake_credentials.h',
- 'src/core/lib/security/credentials/google_default/google_default_credentials.h',
- 'src/core/lib/security/credentials/iam/iam_credentials.h',
- 'src/core/lib/security/credentials/jwt/json_token.h',
- 'src/core/lib/security/credentials/jwt/jwt_credentials.h',
- 'src/core/lib/security/credentials/jwt/jwt_verifier.h',
- 'src/core/lib/security/credentials/oauth2/oauth2_credentials.h',
- 'src/core/lib/security/credentials/plugin/plugin_credentials.h',
- 'src/core/lib/security/credentials/ssl/ssl_credentials.h',
- 'src/core/lib/security/security_connector/alts_security_connector.h',
- 'src/core/lib/security/security_connector/security_connector.h',
- 'src/core/lib/security/transport/auth_filters.h',
- 'src/core/lib/security/transport/secure_endpoint.h',
- 'src/core/lib/security/transport/security_handshaker.h',
- 'src/core/lib/security/transport/target_authority_table.h',
- 'src/core/lib/security/transport/tsi_error.h',
- 'src/core/lib/security/util/json_util.h',
- 'src/core/tsi/alts/crypt/gsec.h',
- 'src/core/tsi/alts/frame_protector/alts_counter.h',
- 'src/core/tsi/alts/frame_protector/alts_crypter.h',
- 'src/core/tsi/alts/frame_protector/alts_frame_protector.h',
- 'src/core/tsi/alts/frame_protector/alts_record_protocol_crypter_common.h',
- 'src/core/tsi/alts/frame_protector/frame_handler.h',
- 'src/core/tsi/alts/handshaker/alts_handshaker_client.h',
- 'src/core/tsi/alts/handshaker/alts_tsi_event.h',
- 'src/core/tsi/alts/handshaker/alts_tsi_handshaker.h',
- 'src/core/tsi/alts/handshaker/alts_tsi_handshaker_private.h',
- 'src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.h',
- 'src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.h',
- 'src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol.h',
- 'src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.h',
- 'src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.h',
- 'src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.h',
- 'src/core/lib/security/credentials/alts/check_gcp_environment.h',
- 'src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h',
- 'src/core/tsi/alts/handshaker/alts_handshaker_service_api.h',
- 'src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.h',
- 'src/core/tsi/alts/handshaker/alts_tsi_utils.h',
- 'src/core/tsi/alts/handshaker/transport_security_common_api.h',
- 'src/core/tsi/alts/handshaker/altscontext.pb.h',
- 'src/core/tsi/alts/handshaker/handshaker.pb.h',
- 'src/core/tsi/alts/handshaker/transport_security_common.pb.h',
- 'third_party/nanopb/pb.h',
- 'third_party/nanopb/pb_common.h',
- 'third_party/nanopb/pb_decode.h',
- 'third_party/nanopb/pb_encode.h',
- 'src/core/tsi/transport_security.h',
- 'src/core/tsi/transport_security_adapter.h',
- 'src/core/tsi/transport_security_interface.h',
- 'src/core/ext/transport/chttp2/client/chttp2_connector.h',
- 'src/core/tsi/alts_transport_security.h',
- 'src/core/tsi/fake_transport_security.h',
- 'src/core/tsi/ssl/session_cache/ssl_session.h',
- 'src/core/tsi/ssl/session_cache/ssl_session_cache.h',
- 'src/core/tsi/ssl_transport_security.h',
- 'src/core/tsi/ssl_types.h',
- 'src/core/tsi/transport_security_grpc.h',
- 'src/core/ext/transport/chttp2/server/chttp2_server.h'
+ 'src/core/ext/transport/cronet/transport/cronet_transport.h',
+ 'third_party/objective_c/Cronet/bidirectional_stream_c.h',
+ 'third_party/nanopb/pb.h',
+ 'third_party/nanopb/pb_common.h',
+ 'third_party/nanopb/pb_decode.h',
+ 'third_party/nanopb/pb_encode.h'
end
- s.subspec 'Cronet-Tests' do |ss|
+ s.subspec 'Tests' do |ss|
ss.header_mappings_dir = '.'
- ss.dependency "#{s.name}/Cronet-Interface", version
- ss.dependency "#{s.name}/Cronet-Implementation", version
+ ss.dependency "#{s.name}/Interface", version
+ ss.dependency "#{s.name}/Implementation", version
ss.source_files = 'test/core/util/test_config.cc',
'test/core/util/test_config.h',
@@ -2038,6 +1123,7 @@
'test/core/end2end/fixtures/proxy.cc',
'test/core/iomgr/endpoint_tests.cc',
'test/core/util/debugger_macros.cc',
+ 'test/core/util/fuzzer_util.cc',
'test/core/util/grpc_profiler.cc',
'test/core/util/histogram.cc',
'test/core/util/memory_counters.cc',
@@ -2060,6 +1146,7 @@
'test/core/end2end/fixtures/proxy.h',
'test/core/iomgr/endpoint_tests.h',
'test/core/util/debugger_macros.h',
+ 'test/core/util/fuzzer_util.h',
'test/core/util/grpc_profiler.h',
'test/core/util/histogram.h',
'test/core/util/memory_counters.h',
@@ -2080,6 +1167,7 @@
'test/core/end2end/tests/bad_ping.cc',
'test/core/end2end/tests/binary_metadata.cc',
'test/core/end2end/tests/call_creds.cc',
+ 'test/core/end2end/tests/call_host_override.cc',
'test/core/end2end/tests/cancel_after_accept.cc',
'test/core/end2end/tests/cancel_after_client_done.cc',
'test/core/end2end/tests/cancel_after_invoke.cc',
@@ -2126,6 +1214,7 @@
'test/core/end2end/tests/retry_exceeds_buffer_size_in_initial_batch.cc',
'test/core/end2end/tests/retry_exceeds_buffer_size_in_subsequent_batch.cc',
'test/core/end2end/tests/retry_non_retriable_status.cc',
+ 'test/core/end2end/tests/retry_non_retriable_status_before_recv_trailing_metadata_started.cc',
'test/core/end2end/tests/retry_recv_initial_metadata.cc',
'test/core/end2end/tests/retry_recv_message.cc',
'test/core/end2end/tests/retry_server_pushback_delay.cc',
diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec
index 149687e..17e650c 100644
--- a/gRPC-ProtoRPC.podspec
+++ b/gRPC-ProtoRPC.podspec
@@ -21,7 +21,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-ProtoRPC'
- version = '1.11.0-dev'
+ version = '1.13.0-dev'
s.version = version
s.summary = 'RPC library for Protocol Buffers, based on gRPC'
s.homepage = 'https://grpc.io'
diff --git a/gRPC-RxLibrary.podspec b/gRPC-RxLibrary.podspec
index 2497174..b9288af 100644
--- a/gRPC-RxLibrary.podspec
+++ b/gRPC-RxLibrary.podspec
@@ -21,7 +21,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-RxLibrary'
- version = '1.11.0-dev'
+ version = '1.13.0-dev'
s.version = version
s.summary = 'Reactive Extensions library for iOS/OSX.'
s.homepage = 'https://grpc.io'
diff --git a/gRPC.podspec b/gRPC.podspec
index 68e06b5..afc4581 100644
--- a/gRPC.podspec
+++ b/gRPC.podspec
@@ -20,7 +20,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC'
- version = '1.11.0-dev'
+ version = '1.13.0-dev'
s.version = version
s.summary = 'gRPC client library for iOS/OSX'
s.homepage = 'https://grpc.io'
diff --git a/grpc.def b/grpc.def
index d64629f..6a91214 100644
--- a/grpc.def
+++ b/grpc.def
@@ -115,6 +115,12 @@
grpc_server_add_secure_http2_port
grpc_call_set_credentials
grpc_server_credentials_set_auth_metadata_processor
+ grpc_alts_credentials_client_options_create
+ grpc_alts_credentials_server_options_create
+ grpc_alts_credentials_client_options_add_target_service_account
+ grpc_alts_credentials_options_destroy
+ grpc_alts_credentials_create
+ grpc_alts_server_credentials_create
grpc_raw_byte_buffer_create
grpc_raw_compressed_byte_buffer_create
grpc_byte_buffer_copy
@@ -185,6 +191,7 @@
gpr_cpu_current_cpu
gpr_log_severity_string
gpr_log
+ gpr_should_log
gpr_log_message
gpr_set_log_verbosity
gpr_log_verbosity_init
diff --git a/grpc.gemspec b/grpc.gemspec
index 920254a..2a66801 100644
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -201,6 +201,7 @@
s.files += %w( src/core/ext/filters/http/client/http_client_filter.h )
s.files += %w( src/core/ext/filters/http/message_compress/message_compress_filter.h )
s.files += %w( src/core/ext/filters/http/server/http_server_filter.h )
+ s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h )
s.files += %w( src/core/lib/security/context/security_context.h )
s.files += %w( src/core/lib/security/credentials/alts/alts_credentials.h )
s.files += %w( src/core/lib/security/credentials/composite/composite_credentials.h )
@@ -252,8 +253,8 @@
s.files += %w( third_party/nanopb/pb_decode.h )
s.files += %w( third_party/nanopb/pb_encode.h )
s.files += %w( src/core/tsi/transport_security.h )
- s.files += %w( src/core/tsi/transport_security_adapter.h )
s.files += %w( src/core/tsi/transport_security_interface.h )
+ s.files += %w( src/core/ext/transport/chttp2/client/authority.h )
s.files += %w( src/core/ext/transport/chttp2/client/chttp2_connector.h )
s.files += %w( src/core/ext/filters/client_channel/backup_poller.h )
s.files += %w( src/core/ext/filters/client_channel/client_channel.h )
@@ -431,6 +432,7 @@
s.files += %w( src/core/ext/filters/load_reporting/server_load_reporting_plugin.h )
s.files += %w( src/core/ext/filters/max_age/max_age_filter.h )
s.files += %w( src/core/ext/filters/message_size/message_size_filter.h )
+ s.files += %w( src/core/ext/filters/http/client_authority_filter.h )
s.files += %w( src/core/ext/filters/workarounds/workaround_cronet_compression_filter.h )
s.files += %w( src/core/ext/filters/workarounds/workaround_utils.h )
s.files += %w( src/core/lib/surface/init.cc )
@@ -672,9 +674,9 @@
s.files += %w( third_party/nanopb/pb_decode.c )
s.files += %w( third_party/nanopb/pb_encode.c )
s.files += %w( src/core/tsi/transport_security.cc )
- s.files += %w( src/core/tsi/transport_security_adapter.cc )
s.files += %w( src/core/ext/transport/chttp2/client/insecure/channel_create.cc )
s.files += %w( src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc )
+ s.files += %w( src/core/ext/transport/chttp2/client/authority.cc )
s.files += %w( src/core/ext/transport/chttp2/client/chttp2_connector.cc )
s.files += %w( src/core/ext/filters/client_channel/backup_poller.cc )
s.files += %w( src/core/ext/filters/client_channel/channel_connectivity.cc )
@@ -719,7 +721,6 @@
s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c )
s.files += %w( src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc )
s.files += %w( src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc )
- s.files += %w( src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc )
s.files += %w( src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc )
@@ -732,6 +733,7 @@
s.files += %w( src/core/ext/census/grpc_context.cc )
s.files += %w( src/core/ext/filters/max_age/max_age_filter.cc )
s.files += %w( src/core/ext/filters/message_size/message_size_filter.cc )
+ s.files += %w( src/core/ext/filters/http/client_authority_filter.cc )
s.files += %w( src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc )
s.files += %w( src/core/ext/filters/workarounds/workaround_utils.cc )
s.files += %w( src/core/plugin_registry/grpc_plugin_registry.cc )
diff --git a/grpc.gyp b/grpc.gyp
index 36b89f3..5726719 100644
--- a/grpc.gyp
+++ b/grpc.gyp
@@ -481,9 +481,9 @@
'third_party/nanopb/pb_decode.c',
'third_party/nanopb/pb_encode.c',
'src/core/tsi/transport_security.cc',
- 'src/core/tsi/transport_security_adapter.cc',
'src/core/ext/transport/chttp2/client/insecure/channel_create.cc',
'src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc',
+ 'src/core/ext/transport/chttp2/client/authority.cc',
'src/core/ext/transport/chttp2/client/chttp2_connector.cc',
'src/core/ext/filters/client_channel/backup_poller.cc',
'src/core/ext/filters/client_channel/channel_connectivity.cc',
@@ -528,7 +528,6 @@
'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c',
'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc',
'src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc',
- 'src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc',
'src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc',
@@ -541,6 +540,7 @@
'src/core/ext/census/grpc_context.cc',
'src/core/ext/filters/max_age/max_age_filter.cc',
'src/core/ext/filters/message_size/message_size_filter.cc',
+ 'src/core/ext/filters/http/client_authority_filter.cc',
'src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc',
'src/core/ext/filters/workarounds/workaround_utils.cc',
'src/core/plugin_registry/grpc_plugin_registry.cc',
@@ -576,6 +576,7 @@
'test/core/end2end/fixtures/proxy.cc',
'test/core/iomgr/endpoint_tests.cc',
'test/core/util/debugger_macros.cc',
+ 'test/core/util/fuzzer_util.cc',
'test/core/util/grpc_profiler.cc',
'test/core/util/histogram.cc',
'test/core/util/memory_counters.cc',
@@ -806,6 +807,7 @@
'test/core/end2end/fixtures/proxy.cc',
'test/core/iomgr/endpoint_tests.cc',
'test/core/util/debugger_macros.cc',
+ 'test/core/util/fuzzer_util.cc',
'test/core/util/grpc_profiler.cc',
'test/core/util/histogram.cc',
'test/core/util/memory_counters.cc',
@@ -1211,6 +1213,7 @@
'src/core/ext/transport/chttp2/server/chttp2_server.cc',
'src/core/ext/transport/chttp2/client/insecure/channel_create.cc',
'src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc',
+ 'src/core/ext/transport/chttp2/client/authority.cc',
'src/core/ext/transport/chttp2/client/chttp2_connector.cc',
'src/core/ext/filters/client_channel/backup_poller.cc',
'src/core/ext/filters/client_channel/channel_connectivity.cc',
@@ -1255,11 +1258,11 @@
'third_party/nanopb/pb_decode.c',
'third_party/nanopb/pb_encode.c',
'src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc',
- 'src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc',
'src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc',
'src/core/ext/census/grpc_context.cc',
'src/core/ext/filters/max_age/max_age_filter.cc',
'src/core/ext/filters/message_size/message_size_filter.cc',
+ 'src/core/ext/filters/http/client_authority_filter.cc',
'src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc',
'src/core/ext/filters/workarounds/workaround_utils.cc',
'src/core/plugin_registry/grpc_unsecure_plugin_registry.cc',
@@ -1338,7 +1341,6 @@
'src/cpp/server/server_posix.cc',
'src/cpp/thread_manager/thread_manager.cc',
'src/cpp/util/byte_buffer_cc.cc',
- 'src/cpp/util/slice_cc.cc',
'src/cpp/util/status.cc',
'src/cpp/util/string_ref.cc',
'src/cpp/util/time_cc.cc',
@@ -1486,7 +1488,6 @@
'src/cpp/server/server_posix.cc',
'src/cpp/thread_manager/thread_manager.cc',
'src/cpp/util/byte_buffer_cc.cc',
- 'src/cpp/util/slice_cc.cc',
'src/cpp/util/status.cc',
'src/cpp/util/string_ref.cc',
'src/cpp/util/time_cc.cc',
@@ -1636,6 +1637,16 @@
],
},
{
+ 'target_name': 'lb_load_data_store',
+ 'type': 'static_library',
+ 'dependencies': [
+ 'grpc++',
+ ],
+ 'sources': [
+ 'src/cpp/server/load_reporter/load_data_store.cc',
+ ],
+ },
+ {
'target_name': 'qps',
'type': 'static_library',
'dependencies': [
@@ -1650,7 +1661,9 @@
'src/proto/grpc/testing/payloads.proto',
'src/proto/grpc/testing/stats.proto',
'src/proto/grpc/testing/control.proto',
- 'src/proto/grpc/testing/services.proto',
+ 'src/proto/grpc/testing/benchmark_service.proto',
+ 'src/proto/grpc/testing/report_qps_scenario_service.proto',
+ 'src/proto/grpc/testing/worker_service.proto',
'test/cpp/qps/benchmark_config.cc',
'test/cpp/qps/client_async.cc',
'test/cpp/qps/client_sync.cc',
@@ -2573,6 +2586,7 @@
'test/core/end2end/tests/bad_ping.cc',
'test/core/end2end/tests/binary_metadata.cc',
'test/core/end2end/tests/call_creds.cc',
+ 'test/core/end2end/tests/call_host_override.cc',
'test/core/end2end/tests/cancel_after_accept.cc',
'test/core/end2end/tests/cancel_after_client_done.cc',
'test/core/end2end/tests/cancel_after_invoke.cc',
@@ -2619,6 +2633,7 @@
'test/core/end2end/tests/retry_exceeds_buffer_size_in_initial_batch.cc',
'test/core/end2end/tests/retry_exceeds_buffer_size_in_subsequent_batch.cc',
'test/core/end2end/tests/retry_non_retriable_status.cc',
+ 'test/core/end2end/tests/retry_non_retriable_status_before_recv_trailing_metadata_started.cc',
'test/core/end2end/tests/retry_recv_initial_metadata.cc',
'test/core/end2end/tests/retry_recv_message.cc',
'test/core/end2end/tests/retry_server_pushback_delay.cc',
@@ -2661,6 +2676,7 @@
'test/core/end2end/tests/bad_hostname.cc',
'test/core/end2end/tests/bad_ping.cc',
'test/core/end2end/tests/binary_metadata.cc',
+ 'test/core/end2end/tests/call_host_override.cc',
'test/core/end2end/tests/cancel_after_accept.cc',
'test/core/end2end/tests/cancel_after_client_done.cc',
'test/core/end2end/tests/cancel_after_invoke.cc',
@@ -2707,6 +2723,7 @@
'test/core/end2end/tests/retry_exceeds_buffer_size_in_initial_batch.cc',
'test/core/end2end/tests/retry_exceeds_buffer_size_in_subsequent_batch.cc',
'test/core/end2end/tests/retry_non_retriable_status.cc',
+ 'test/core/end2end/tests/retry_non_retriable_status_before_recv_trailing_metadata_started.cc',
'test/core/end2end/tests/retry_recv_initial_metadata.cc',
'test/core/end2end/tests/retry_recv_message.cc',
'test/core/end2end/tests/retry_server_pushback_delay.cc',
diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h
index 7c069b3..e1975a8 100644
--- a/include/grpc/grpc_security.h
+++ b/include/grpc/grpc_security.h
@@ -488,6 +488,76 @@
GRPCAPI void grpc_server_credentials_set_auth_metadata_processor(
grpc_server_credentials* creds, grpc_auth_metadata_processor processor);
+/** --- ALTS channel/server credentials --- **/
+
+/**
+ * Main interface for ALTS credentials options. The options will contain
+ * information that will be passed from grpc to TSI layer such as RPC protocol
+ * versions. ALTS client (channel) and server credentials will have their own
+ * implementation of this interface. The APIs listed in this header are
+ * thread-compatible. It is used for experimental purpose for now and subject
+ * to change.
+ */
+typedef struct grpc_alts_credentials_options grpc_alts_credentials_options;
+
+/**
+ * This method creates a grpc ALTS credentials client options instance.
+ * It is used for experimental purpose for now and subject to change.
+ */
+GRPCAPI grpc_alts_credentials_options*
+grpc_alts_credentials_client_options_create();
+
+/**
+ * This method creates a grpc ALTS credentials server options instance.
+ * It is used for experimental purpose for now and subject to change.
+ */
+GRPCAPI grpc_alts_credentials_options*
+grpc_alts_credentials_server_options_create();
+
+/**
+ * This method adds a target service account to grpc client's ALTS credentials
+ * options instance. It is used for experimental purpose for now and subject
+ * to change.
+ *
+ * - options: grpc ALTS credentials options instance.
+ * - service_account: service account of target endpoint.
+ */
+GRPCAPI void grpc_alts_credentials_client_options_add_target_service_account(
+ grpc_alts_credentials_options* options, const char* service_account);
+
+/**
+ * This method destroys a grpc_alts_credentials_options instance by
+ * de-allocating all of its occupied memory. It is used for experimental purpose
+ * for now and subject to change.
+ *
+ * - options: a grpc_alts_credentials_options instance that needs to be
+ * destroyed.
+ */
+GRPCAPI void grpc_alts_credentials_options_destroy(
+ grpc_alts_credentials_options* options);
+
+/**
+ * This method creates an ALTS channel credential object. It is used for
+ * experimental purpose for now and subject to change.
+ *
+ * - options: grpc ALTS credentials options instance for client.
+ *
+ * It returns the created ALTS channel credential object.
+ */
+GRPCAPI grpc_channel_credentials* grpc_alts_credentials_create(
+ const grpc_alts_credentials_options* options);
+
+/**
+ * This method creates an ALTS server credential object. It is used for
+ * experimental purpose for now and subject to change.
+ *
+ * - options: grpc ALTS credentials options instance for server.
+ *
+ * It returns the created ALTS server credential object.
+ */
+GRPCAPI grpc_server_credentials* grpc_alts_server_credentials_create(
+ const grpc_alts_credentials_options* options);
+
#ifdef __cplusplus
}
#endif
diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h
index 03aaa9f..022be5f 100644
--- a/include/grpc/impl/codegen/grpc_types.h
+++ b/include/grpc/impl/codegen/grpc_types.h
@@ -333,6 +333,9 @@
/** Channel arg that carries the bridged objective c object for custom metrics
* logging filter. */
#define GRPC_ARG_MOBILE_LOG_CONFIG "grpc.mobile_log_config"
+/** If non-zero, client authority filter is disabled for the channel */
+#define GRPC_ARG_DISABLE_CLIENT_AUTHORITY_FILTER \
+ "grpc.disable_client_authority_filter"
/** \} */
/** Result of a grpc call. If the caller satisfies the prerequisites of a
diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h
index 819d17c..bf1bf3d 100644
--- a/include/grpc/impl/codegen/port_platform.h
+++ b/include/grpc/impl/codegen/port_platform.h
@@ -500,6 +500,17 @@
#endif /* __GPR_WINDOWS */
#endif /* GRPC_ALLOW_EXCEPTIONS */
+/* Use GPR_LIKELY only in cases where you are sure that a certain outcome is the
+ * most likely. Ideally, also collect performance numbers to justify the claim.
+ */
+#ifdef __GNUC__
+#define GPR_LIKELY(x) __builtin_expect((x), 1)
+#define GPR_UNLIKELY(x) __builtin_expect((x), 0)
+#else /* __GNUC__ */
+#define GPR_LIKELY(x) (x)
+#define GPR_UNLIKELY(x) (x)
+#endif /* __GNUC__ */
+
#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
#endif
diff --git a/include/grpc/support/log.h b/include/grpc/support/log.h
index 2236703..1837d4b 100644
--- a/include/grpc/support/log.h
+++ b/include/grpc/support/log.h
@@ -61,6 +61,8 @@
GPRAPI void gpr_log(const char* file, int line, gpr_log_severity severity,
const char* format, ...) GPR_PRINT_FORMAT_CHECK(4, 5);
+GPRAPI int gpr_should_log(gpr_log_severity severity);
+
GPRAPI void gpr_log_message(const char* file, int line,
gpr_log_severity severity, const char* message);
@@ -91,12 +93,18 @@
an exception in a higher-level language, consider returning error code. */
#define GPR_ASSERT(x) \
do { \
- if (!(x)) { \
+ if (GPR_UNLIKELY(!(x))) { \
gpr_log(GPR_ERROR, "assertion failed: %s", #x); \
abort(); \
} \
} while (0)
+#ifndef NDEBUG
+#define GPR_DEBUG_ASSERT(x) GPR_ASSERT(x)
+#else
+#define GPR_DEBUG_ASSERT(x)
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/include/grpcpp/client_context.h b/include/grpcpp/client_context.h
index 8c12577..1994fcc 100644
--- a/include/grpcpp/client_context.h
+++ b/include/grpcpp/client_context.h
@@ -26,7 +26,7 @@
///
/// Context settings are only relevant to the call they are invoked with, that
/// is to say, they aren't sticky. Some of these settings, such as the
-/// compression options, can be made persistant at channel construction time
+/// compression options, can be made persistent at channel construction time
/// (see \a grpc::CreateCustomChannel).
///
/// \warning ClientContext instances should \em not be reused across rpcs.
diff --git a/include/grpcpp/impl/codegen/byte_buffer.h b/include/grpcpp/impl/codegen/byte_buffer.h
index 8d6a169..86c047e 100644
--- a/include/grpcpp/impl/codegen/byte_buffer.h
+++ b/include/grpcpp/impl/codegen/byte_buffer.h
@@ -31,6 +31,10 @@
namespace grpc {
+class ServerInterface;
+class ByteBuffer;
+class ServerInterface;
+
namespace internal {
class CallOpSendMessage;
template <class R>
@@ -43,6 +47,7 @@
class ServerStreamingHandler;
template <class R>
class DeserializeFuncType;
+class GrpcByteBufferPeer;
} // namespace internal
/// A sequence of bytes.
class ByteBuffer final {
@@ -51,7 +56,30 @@
ByteBuffer() : buffer_(nullptr) {}
/// Construct buffer from \a slices, of which there are \a nslices.
- ByteBuffer(const Slice* slices, size_t nslices);
+ ByteBuffer(const Slice* slices, size_t nslices) {
+ // The following assertions check that the representation of a grpc::Slice
+ // is identical to that of a grpc_slice: it has a grpc_slice field, and
+ // nothing else.
+ static_assert(std::is_same<decltype(slices[0].slice_), grpc_slice>::value,
+ "Slice must have same representation as grpc_slice");
+ static_assert(sizeof(Slice) == sizeof(grpc_slice),
+ "Slice must have same representation as grpc_slice");
+ // The following assertions check that the representation of a ByteBuffer is
+ // identical to grpc_byte_buffer*: it has a grpc_byte_buffer* field,
+ // and nothing else.
+ static_assert(std::is_same<decltype(buffer_), grpc_byte_buffer*>::value,
+ "ByteBuffer must have same representation as "
+ "grpc_byte_buffer*");
+ static_assert(sizeof(ByteBuffer) == sizeof(grpc_byte_buffer*),
+ "ByteBuffer must have same representation as "
+ "grpc_byte_buffer*");
+ // The const_cast is legal if grpc_raw_byte_buffer_create() does no more
+ // than its advertised side effect of increasing the reference count of the
+ // slices it processes, and such an increase does not affect the semantics
+ // seen by the caller of this constructor.
+ buffer_ = g_core_codegen_interface->grpc_raw_byte_buffer_create(
+ reinterpret_cast<grpc_slice*>(const_cast<Slice*>(slices)), nslices);
+ }
/// Constuct a byte buffer by referencing elements of existing buffer
/// \a buf. Wrapper of core function grpc_byte_buffer_copy
@@ -88,16 +116,25 @@
void Release() { buffer_ = nullptr; }
/// Buffer size in bytes.
- size_t Length() const;
+ size_t Length() const {
+ return buffer_ == nullptr
+ ? 0
+ : g_core_codegen_interface->grpc_byte_buffer_length(buffer_);
+ }
/// Swap the state of *this and *other.
- void Swap(ByteBuffer* other);
+ void Swap(ByteBuffer* other) {
+ grpc_byte_buffer* tmp = other->buffer_;
+ other->buffer_ = buffer_;
+ buffer_ = tmp;
+ }
/// Is this ByteBuffer valid?
bool Valid() const { return (buffer_ != nullptr); }
private:
friend class SerializationTraits<ByteBuffer, void>;
+ friend class ServerInterface;
friend class internal::CallOpSendMessage;
template <class R>
friend class internal::CallOpRecvMessage;
@@ -109,6 +146,9 @@
friend class internal::ServerStreamingHandler;
template <class R>
friend class internal::DeserializeFuncType;
+ friend class ProtoBufferReader;
+ friend class ProtoBufferWriter;
+ friend class internal::GrpcByteBufferPeer;
grpc_byte_buffer* buffer_;
diff --git a/include/grpcpp/impl/codegen/core_codegen.h b/include/grpcpp/impl/codegen/core_codegen.h
index 0ca4ad5..e9df96b 100644
--- a/include/grpcpp/impl/codegen/core_codegen.h
+++ b/include/grpcpp/impl/codegen/core_codegen.h
@@ -73,6 +73,7 @@
grpc_byte_buffer* grpc_byte_buffer_copy(grpc_byte_buffer* bb) override;
void grpc_byte_buffer_destroy(grpc_byte_buffer* bb) override;
+ size_t grpc_byte_buffer_length(grpc_byte_buffer* bb) override;
int grpc_byte_buffer_reader_init(grpc_byte_buffer_reader* reader,
grpc_byte_buffer* buffer) override;
@@ -86,6 +87,8 @@
grpc_slice grpc_slice_new_with_user_data(void* p, size_t len,
void (*destroy)(void*),
void* user_data) override;
+ grpc_slice grpc_slice_new_with_len(void* p, size_t len,
+ void (*destroy)(void*, size_t)) override;
grpc_slice grpc_empty_slice() override;
grpc_slice grpc_slice_malloc(size_t length) override;
void grpc_slice_unref(grpc_slice slice) override;
diff --git a/include/grpcpp/impl/codegen/core_codegen_interface.h b/include/grpcpp/impl/codegen/core_codegen_interface.h
index d72f579..1167a18 100644
--- a/include/grpcpp/impl/codegen/core_codegen_interface.h
+++ b/include/grpcpp/impl/codegen/core_codegen_interface.h
@@ -81,6 +81,8 @@
virtual grpc_byte_buffer* grpc_byte_buffer_copy(grpc_byte_buffer* bb) = 0;
virtual void grpc_byte_buffer_destroy(grpc_byte_buffer* bb) = 0;
+ virtual size_t grpc_byte_buffer_length(grpc_byte_buffer* bb)
+ GRPC_MUST_USE_RESULT = 0;
virtual int grpc_byte_buffer_reader_init(grpc_byte_buffer_reader* reader,
grpc_byte_buffer* buffer)
@@ -95,6 +97,9 @@
virtual grpc_slice grpc_slice_new_with_user_data(void* p, size_t len,
void (*destroy)(void*),
void* user_data) = 0;
+ virtual grpc_slice grpc_slice_new_with_len(void* p, size_t len,
+ void (*destroy)(void*,
+ size_t)) = 0;
virtual grpc_call_error grpc_call_cancel_with_status(grpc_call* call,
grpc_status_code status,
const char* description,
diff --git a/include/grpcpp/impl/codegen/proto_buffer_reader.h b/include/grpcpp/impl/codegen/proto_buffer_reader.h
new file mode 100644
index 0000000..9acae47
--- /dev/null
+++ b/include/grpcpp/impl/codegen/proto_buffer_reader.h
@@ -0,0 +1,151 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#ifndef GRPCPP_IMPL_CODEGEN_PROTO_BUFFER_READER_H
+#define GRPCPP_IMPL_CODEGEN_PROTO_BUFFER_READER_H
+
+#include <type_traits>
+
+#include <grpc/impl/codegen/byte_buffer_reader.h>
+#include <grpc/impl/codegen/grpc_types.h>
+#include <grpc/impl/codegen/slice.h>
+#include <grpcpp/impl/codegen/byte_buffer.h>
+#include <grpcpp/impl/codegen/config_protobuf.h>
+#include <grpcpp/impl/codegen/core_codegen_interface.h>
+#include <grpcpp/impl/codegen/serialization_traits.h>
+#include <grpcpp/impl/codegen/status.h>
+
+/// This header provides an object that reads bytes directly from a
+/// grpc::ByteBuffer, via the ZeroCopyInputStream interface
+
+namespace grpc {
+
+extern CoreCodegenInterface* g_core_codegen_interface;
+
+/// This is a specialization of the protobuf class ZeroCopyInputStream
+/// The principle is to get one chunk of data at a time from the proto layer,
+/// with options to backup (re-see some bytes) or skip (forward past some bytes)
+///
+/// Read more about ZeroCopyInputStream interface here:
+/// https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.io.zero_copy_stream#ZeroCopyInputStream
+class ProtoBufferReader : public ::grpc::protobuf::io::ZeroCopyInputStream {
+ public:
+ /// Constructs buffer reader from \a buffer. Will set \a status() to non ok
+ /// if \a buffer is invalid (the internal buffer has not been initialized).
+ explicit ProtoBufferReader(ByteBuffer* buffer)
+ : byte_count_(0), backup_count_(0), status_() {
+ /// Implemented through a grpc_byte_buffer_reader which iterates
+ /// over the slices that make up a byte buffer
+ if (!buffer->Valid() ||
+ !g_core_codegen_interface->grpc_byte_buffer_reader_init(
+ &reader_, buffer->c_buffer())) {
+ status_ = Status(StatusCode::INTERNAL,
+ "Couldn't initialize byte buffer reader");
+ }
+ }
+
+ ~ProtoBufferReader() {
+ if (status_.ok()) {
+ g_core_codegen_interface->grpc_byte_buffer_reader_destroy(&reader_);
+ }
+ }
+
+ /// Give the proto library a chunk of data from the stream. The caller
+ /// may safely read from data[0, size - 1].
+ bool Next(const void** data, int* size) override {
+ if (!status_.ok()) {
+ return false;
+ }
+ /// If we have backed up previously, we need to return the backed-up slice
+ if (backup_count_ > 0) {
+ *data = GRPC_SLICE_START_PTR(slice_) + GRPC_SLICE_LENGTH(slice_) -
+ backup_count_;
+ GPR_CODEGEN_ASSERT(backup_count_ <= INT_MAX);
+ *size = (int)backup_count_;
+ backup_count_ = 0;
+ return true;
+ }
+ /// Otherwise get the next slice from the byte buffer reader
+ if (!g_core_codegen_interface->grpc_byte_buffer_reader_next(&reader_,
+ &slice_)) {
+ return false;
+ }
+ g_core_codegen_interface->grpc_slice_unref(slice_);
+ *data = GRPC_SLICE_START_PTR(slice_);
+ // On win x64, int is only 32bit
+ GPR_CODEGEN_ASSERT(GRPC_SLICE_LENGTH(slice_) <= INT_MAX);
+ byte_count_ += * size = (int)GRPC_SLICE_LENGTH(slice_);
+ return true;
+ }
+
+ /// Returns the status of the buffer reader.
+ Status status() const { return status_; }
+
+ /// The proto library calls this to indicate that we should back up \a count
+ /// bytes that have already been returned by the last call of Next.
+ /// So do the backup and have that ready for a later Next.
+ void BackUp(int count) override {
+ GPR_CODEGEN_ASSERT(count <= static_cast<int>(GRPC_SLICE_LENGTH(slice_)));
+ backup_count_ = count;
+ }
+
+ /// The proto library calls this to skip over \a count bytes. Implement this
+ /// using Next and BackUp combined.
+ bool Skip(int count) override {
+ const void* data;
+ int size;
+ while (Next(&data, &size)) {
+ if (size >= count) {
+ BackUp(size - count);
+ return true;
+ }
+ // size < count;
+ count -= size;
+ }
+ // error or we have too large count;
+ return false;
+ }
+
+ /// Returns the total number of bytes read since this object was created.
+ grpc::protobuf::int64 ByteCount() const override {
+ return byte_count_ - backup_count_;
+ }
+
+ // These protected members are needed to support internal optimizations.
+ // they expose internal bits of grpc core that are NOT stable. If you have
+ // a use case needs to use one of these functions, please send an email to
+ // https://groups.google.com/forum/#!forum/grpc-io.
+ protected:
+ void set_byte_count(int64_t byte_count) { byte_count_ = byte_count; }
+ int64_t backup_count() { return backup_count_; }
+ void set_backup_count(int64_t backup_count) { backup_count_ = backup_count; }
+ grpc_byte_buffer_reader* reader() { return &reader_; }
+ grpc_slice* slice() { return &slice_; }
+
+ private:
+ int64_t byte_count_; ///< total bytes read since object creation
+ int64_t backup_count_; ///< how far backed up in the stream we are
+ grpc_byte_buffer_reader reader_; ///< internal object to read \a grpc_slice
+ ///< from the \a grpc_byte_buffer
+ grpc_slice slice_; ///< current slice passed back to the caller
+ Status status_; ///< status of the entire object
+};
+
+} // namespace grpc
+
+#endif // GRPCPP_IMPL_CODEGEN_PROTO_BUFFER_READER_H
diff --git a/include/grpcpp/impl/codegen/proto_buffer_writer.h b/include/grpcpp/impl/codegen/proto_buffer_writer.h
new file mode 100644
index 0000000..fdff467
--- /dev/null
+++ b/include/grpcpp/impl/codegen/proto_buffer_writer.h
@@ -0,0 +1,167 @@
+/*
+ *
+ * Copyright 2018 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 GRPCPP_IMPL_CODEGEN_PROTO_BUFFER_WRITER_H
+#define GRPCPP_IMPL_CODEGEN_PROTO_BUFFER_WRITER_H
+
+#include <type_traits>
+
+#include <grpc/impl/codegen/grpc_types.h>
+#include <grpc/impl/codegen/slice.h>
+#include <grpcpp/impl/codegen/byte_buffer.h>
+#include <grpcpp/impl/codegen/config_protobuf.h>
+#include <grpcpp/impl/codegen/core_codegen_interface.h>
+#include <grpcpp/impl/codegen/serialization_traits.h>
+#include <grpcpp/impl/codegen/status.h>
+
+/// This header provides an object that writes bytes directly into a
+/// grpc::ByteBuffer, via the ZeroCopyOutputStream interface
+
+namespace grpc {
+
+extern CoreCodegenInterface* g_core_codegen_interface;
+
+// Forward declaration for testing use only
+namespace internal {
+class ProtoBufferWriterPeer;
+} // namespace internal
+
+const int kProtoBufferWriterMaxBufferLength = 1024 * 1024;
+
+/// This is a specialization of the protobuf class ZeroCopyOutputStream.
+/// The principle is to give the proto layer one buffer of bytes at a time
+/// that it can use to serialize the next portion of the message, with the
+/// option to "backup" if more buffer is given than required at the last buffer.
+///
+/// Read more about ZeroCopyOutputStream interface here:
+/// https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.io.zero_copy_stream#ZeroCopyOutputStream
+class ProtoBufferWriter : public ::grpc::protobuf::io::ZeroCopyOutputStream {
+ public:
+ /// Constructor for this derived class
+ ///
+ /// \param[out] byte_buffer A pointer to the grpc::ByteBuffer created
+ /// \param block_size How big are the chunks to allocate at a time
+ /// \param total_size How many total bytes are required for this proto
+ ProtoBufferWriter(ByteBuffer* byte_buffer, int block_size, int total_size)
+ : block_size_(block_size),
+ total_size_(total_size),
+ byte_count_(0),
+ have_backup_(false) {
+ GPR_CODEGEN_ASSERT(!byte_buffer->Valid());
+ /// Create an empty raw byte buffer and look at its underlying slice buffer
+ grpc_byte_buffer* bp =
+ g_core_codegen_interface->grpc_raw_byte_buffer_create(NULL, 0);
+ byte_buffer->set_buffer(bp);
+ slice_buffer_ = &bp->data.raw.slice_buffer;
+ }
+
+ ~ProtoBufferWriter() {
+ if (have_backup_) {
+ g_core_codegen_interface->grpc_slice_unref(backup_slice_);
+ }
+ }
+
+ /// Give the proto library the next buffer of bytes and its size. It is
+ /// safe for the caller to write from data[0, size - 1].
+ bool Next(void** data, int* size) override {
+ // Protobuf should not ask for more memory than total_size_.
+ GPR_CODEGEN_ASSERT(byte_count_ < total_size_);
+ // 1. Use the remaining backup slice if we have one
+ // 2. Otherwise allocate a slice, up to the remaining length needed
+ // or our maximum allocation size
+ // 3. Provide the slice start and size available
+ // 4. Add the slice being returned to the slice buffer
+ size_t remain = total_size_ - byte_count_;
+ if (have_backup_) {
+ /// If we have a backup slice, we should use it first
+ slice_ = backup_slice_;
+ have_backup_ = false;
+ if (GRPC_SLICE_LENGTH(slice_) > remain) {
+ GRPC_SLICE_SET_LENGTH(slice_, remain);
+ }
+ } else {
+ // When less than a whole block is needed, only allocate that much.
+ // But make sure the allocated slice is not inlined.
+ size_t allocate_length =
+ remain > static_cast<size_t>(block_size_) ? block_size_ : remain;
+ slice_ = g_core_codegen_interface->grpc_slice_malloc(
+ allocate_length > GRPC_SLICE_INLINED_SIZE
+ ? allocate_length
+ : GRPC_SLICE_INLINED_SIZE + 1);
+ }
+ *data = GRPC_SLICE_START_PTR(slice_);
+ // On win x64, int is only 32bit
+ GPR_CODEGEN_ASSERT(GRPC_SLICE_LENGTH(slice_) <= INT_MAX);
+ byte_count_ += * size = (int)GRPC_SLICE_LENGTH(slice_);
+ g_core_codegen_interface->grpc_slice_buffer_add(slice_buffer_, slice_);
+ return true;
+ }
+
+ /// Backup by \a count bytes because Next returned more bytes than needed
+ /// (only used in the last buffer). \a count must be less than or equal too
+ /// the last buffer returned from next.
+ void BackUp(int count) override {
+ /// 1. Remove the partially-used last slice from the slice buffer
+ /// 2. Split it into the needed (if any) and unneeded part
+ /// 3. Add the needed part back to the slice buffer
+ /// 4. Mark that we still have the remaining part (for later use/unref)
+ GPR_CODEGEN_ASSERT(count <= static_cast<int>(GRPC_SLICE_LENGTH(slice_)));
+ g_core_codegen_interface->grpc_slice_buffer_pop(slice_buffer_);
+ if ((size_t)count == GRPC_SLICE_LENGTH(slice_)) {
+ backup_slice_ = slice_;
+ } else {
+ backup_slice_ = g_core_codegen_interface->grpc_slice_split_tail(
+ &slice_, GRPC_SLICE_LENGTH(slice_) - count);
+ g_core_codegen_interface->grpc_slice_buffer_add(slice_buffer_, slice_);
+ }
+ // It's dangerous to keep an inlined grpc_slice as the backup slice, since
+ // on a following Next() call, a reference will be returned to this slice
+ // via GRPC_SLICE_START_PTR, which will not be an address held by
+ // slice_buffer_.
+ have_backup_ = backup_slice_.refcount != NULL;
+ byte_count_ -= count;
+ }
+
+ /// Returns the total number of bytes written since this object was created.
+ grpc::protobuf::int64 ByteCount() const override { return byte_count_; }
+
+ // These protected members are needed to support internal optimizations.
+ // they expose internal bits of grpc core that are NOT stable. If you have
+ // a use case needs to use one of these functions, please send an email to
+ // https://groups.google.com/forum/#!forum/grpc-io.
+ protected:
+ grpc_slice_buffer* slice_buffer() { return slice_buffer_; }
+ void set_byte_count(int64_t byte_count) { byte_count_ = byte_count; }
+
+ private:
+ // friend for testing purposes only
+ friend class internal::ProtoBufferWriterPeer;
+ const int block_size_; ///< size to alloc for each new \a grpc_slice needed
+ const int total_size_; ///< byte size of proto being serialized
+ int64_t byte_count_; ///< bytes written since this object was created
+ grpc_slice_buffer*
+ slice_buffer_; ///< internal buffer of slices holding the serialized data
+ bool have_backup_; ///< if we are holding a backup slice or not
+ grpc_slice backup_slice_; ///< holds space we can still write to, if the
+ ///< caller has called BackUp
+ grpc_slice slice_; ///< current slice passed back to the caller
+};
+
+} // namespace grpc
+
+#endif // GRPCPP_IMPL_CODEGEN_PROTO_BUFFER_WRITER_H
diff --git a/include/grpcpp/impl/codegen/proto_utils.h b/include/grpcpp/impl/codegen/proto_utils.h
index 81438ee..d9db6de 100644
--- a/include/grpcpp/impl/codegen/proto_utils.h
+++ b/include/grpcpp/impl/codegen/proto_utils.h
@@ -24,203 +24,61 @@
#include <grpc/impl/codegen/byte_buffer_reader.h>
#include <grpc/impl/codegen/grpc_types.h>
#include <grpc/impl/codegen/slice.h>
+#include <grpcpp/impl/codegen/byte_buffer.h>
#include <grpcpp/impl/codegen/config_protobuf.h>
#include <grpcpp/impl/codegen/core_codegen_interface.h>
+#include <grpcpp/impl/codegen/proto_buffer_reader.h>
+#include <grpcpp/impl/codegen/proto_buffer_writer.h>
#include <grpcpp/impl/codegen/serialization_traits.h>
+#include <grpcpp/impl/codegen/slice.h>
#include <grpcpp/impl/codegen/status.h>
+/// This header provides serialization and deserialization between gRPC
+/// messages serialized using protobuf and the C++ objects they represent.
+
namespace grpc {
extern CoreCodegenInterface* g_core_codegen_interface;
-namespace internal {
-
-class GrpcBufferWriterPeer;
-
-const int kGrpcBufferWriterMaxBufferLength = 1024 * 1024;
-
-class GrpcBufferWriter : public ::grpc::protobuf::io::ZeroCopyOutputStream {
- public:
- GrpcBufferWriter(grpc_byte_buffer** bp, int block_size, int total_size)
- : block_size_(block_size),
- total_size_(total_size),
- byte_count_(0),
- have_backup_(false) {
- *bp = g_core_codegen_interface->grpc_raw_byte_buffer_create(NULL, 0);
- slice_buffer_ = &(*bp)->data.raw.slice_buffer;
- }
-
- ~GrpcBufferWriter() override {
- if (have_backup_) {
- g_core_codegen_interface->grpc_slice_unref(backup_slice_);
- }
- }
-
- bool Next(void** data, int* size) override {
- // Protobuf should not ask for more memory than total_size_.
- GPR_CODEGEN_ASSERT(byte_count_ < total_size_);
- size_t remain = total_size_ - byte_count_;
- if (have_backup_) {
- slice_ = backup_slice_;
- have_backup_ = false;
- if (GRPC_SLICE_LENGTH(slice_) > remain) {
- GRPC_SLICE_SET_LENGTH(slice_, remain);
- }
- } else {
- // When less than a whole block is needed, only allocate that much.
- // But make sure the allocated slice is not inlined.
- size_t allocate_length =
- remain > static_cast<size_t>(block_size_) ? block_size_ : remain;
- slice_ = g_core_codegen_interface->grpc_slice_malloc(
- allocate_length > GRPC_SLICE_INLINED_SIZE
- ? allocate_length
- : GRPC_SLICE_INLINED_SIZE + 1);
- }
- *data = GRPC_SLICE_START_PTR(slice_);
- // On win x64, int is only 32bit
- GPR_CODEGEN_ASSERT(GRPC_SLICE_LENGTH(slice_) <= INT_MAX);
- byte_count_ += * size = (int)GRPC_SLICE_LENGTH(slice_);
- g_core_codegen_interface->grpc_slice_buffer_add(slice_buffer_, slice_);
- return true;
- }
-
- void BackUp(int count) override {
- g_core_codegen_interface->grpc_slice_buffer_pop(slice_buffer_);
- if ((size_t)count == GRPC_SLICE_LENGTH(slice_)) {
- backup_slice_ = slice_;
- } else {
- backup_slice_ = g_core_codegen_interface->grpc_slice_split_tail(
- &slice_, GRPC_SLICE_LENGTH(slice_) - count);
- g_core_codegen_interface->grpc_slice_buffer_add(slice_buffer_, slice_);
- }
- // It's dangerous to keep an inlined grpc_slice as the backup slice, since
- // on a following Next() call, a reference will be returned to this slice
- // via GRPC_SLICE_START_PTR, which will not be an adddress held by
- // slice_buffer_.
- have_backup_ = backup_slice_.refcount != NULL;
- byte_count_ -= count;
- }
-
- grpc::protobuf::int64 ByteCount() const override { return byte_count_; }
-
- protected:
- friend class GrpcBufferWriterPeer;
- const int block_size_;
- const int total_size_;
- int64_t byte_count_;
- grpc_slice_buffer* slice_buffer_;
- bool have_backup_;
- grpc_slice backup_slice_;
- grpc_slice slice_;
-};
-
-class GrpcBufferReader : public ::grpc::protobuf::io::ZeroCopyInputStream {
- public:
- explicit GrpcBufferReader(grpc_byte_buffer* buffer)
- : byte_count_(0), backup_count_(0), status_() {
- if (!g_core_codegen_interface->grpc_byte_buffer_reader_init(&reader_,
- buffer)) {
- status_ = Status(StatusCode::INTERNAL,
- "Couldn't initialize byte buffer reader");
- }
- }
- ~GrpcBufferReader() override {
- g_core_codegen_interface->grpc_byte_buffer_reader_destroy(&reader_);
- }
-
- bool Next(const void** data, int* size) override {
- if (!status_.ok()) {
- return false;
- }
- if (backup_count_ > 0) {
- *data = GRPC_SLICE_START_PTR(slice_) + GRPC_SLICE_LENGTH(slice_) -
- backup_count_;
- GPR_CODEGEN_ASSERT(backup_count_ <= INT_MAX);
- *size = (int)backup_count_;
- backup_count_ = 0;
- return true;
- }
- if (!g_core_codegen_interface->grpc_byte_buffer_reader_next(&reader_,
- &slice_)) {
- return false;
- }
- g_core_codegen_interface->grpc_slice_unref(slice_);
- *data = GRPC_SLICE_START_PTR(slice_);
- // On win x64, int is only 32bit
- GPR_CODEGEN_ASSERT(GRPC_SLICE_LENGTH(slice_) <= INT_MAX);
- byte_count_ += * size = (int)GRPC_SLICE_LENGTH(slice_);
- return true;
- }
-
- Status status() const { return status_; }
-
- void BackUp(int count) override { backup_count_ = count; }
-
- bool Skip(int count) override {
- const void* data;
- int size;
- while (Next(&data, &size)) {
- if (size >= count) {
- BackUp(size - count);
- return true;
- }
- // size < count;
- count -= size;
- }
- // error or we have too large count;
- return false;
- }
-
- grpc::protobuf::int64 ByteCount() const override {
- return byte_count_ - backup_count_;
- }
-
- protected:
- int64_t byte_count_;
- int64_t backup_count_;
- grpc_byte_buffer_reader reader_;
- grpc_slice slice_;
- Status status_;
-};
-
-// BufferWriter must be a subclass of io::ZeroCopyOutputStream.
-template <class BufferWriter, class T>
-Status GenericSerialize(const grpc::protobuf::Message& msg,
- grpc_byte_buffer** bp, bool* own_buffer) {
- static_assert(
- std::is_base_of<protobuf::io::ZeroCopyOutputStream, BufferWriter>::value,
- "BufferWriter must be a subclass of io::ZeroCopyOutputStream");
+// ProtoBufferWriter must be a subclass of ::protobuf::io::ZeroCopyOutputStream.
+template <class ProtoBufferWriter, class T>
+Status GenericSerialize(const grpc::protobuf::Message& msg, ByteBuffer* bb,
+ bool* own_buffer) {
+ static_assert(std::is_base_of<protobuf::io::ZeroCopyOutputStream,
+ ProtoBufferWriter>::value,
+ "ProtoBufferWriter must be a subclass of "
+ "::protobuf::io::ZeroCopyOutputStream");
*own_buffer = true;
int byte_size = msg.ByteSize();
if ((size_t)byte_size <= GRPC_SLICE_INLINED_SIZE) {
- grpc_slice slice = g_core_codegen_interface->grpc_slice_malloc(byte_size);
- GPR_CODEGEN_ASSERT(
- GRPC_SLICE_END_PTR(slice) ==
- msg.SerializeWithCachedSizesToArray(GRPC_SLICE_START_PTR(slice)));
- *bp = g_core_codegen_interface->grpc_raw_byte_buffer_create(&slice, 1);
- g_core_codegen_interface->grpc_slice_unref(slice);
+ Slice slice(byte_size);
+ // We serialize directly into the allocated slices memory
+ GPR_CODEGEN_ASSERT(slice.end() == msg.SerializeWithCachedSizesToArray(
+ const_cast<uint8_t*>(slice.begin())));
+ ByteBuffer tmp(&slice, 1);
+ bb->Swap(&tmp);
return g_core_codegen_interface->ok();
}
- BufferWriter writer(bp, kGrpcBufferWriterMaxBufferLength, byte_size);
+ ProtoBufferWriter writer(bb, kProtoBufferWriterMaxBufferLength, byte_size);
return msg.SerializeToZeroCopyStream(&writer)
? g_core_codegen_interface->ok()
: Status(StatusCode::INTERNAL, "Failed to serialize message");
}
-// BufferReader must be a subclass of io::ZeroCopyInputStream.
-template <class BufferReader, class T>
-Status GenericDeserialize(grpc_byte_buffer* buffer,
- grpc::protobuf::Message* msg) {
- static_assert(
- std::is_base_of<protobuf::io::ZeroCopyInputStream, BufferReader>::value,
- "BufferReader must be a subclass of io::ZeroCopyInputStream");
+// BufferReader must be a subclass of ::protobuf::io::ZeroCopyInputStream.
+template <class ProtoBufferReader, class T>
+Status GenericDeserialize(ByteBuffer* buffer, grpc::protobuf::Message* msg) {
+ static_assert(std::is_base_of<protobuf::io::ZeroCopyInputStream,
+ ProtoBufferReader>::value,
+ "ProtoBufferReader must be a subclass of "
+ "::protobuf::io::ZeroCopyInputStream");
if (buffer == nullptr) {
return Status(StatusCode::INTERNAL, "No payload");
}
Status result = g_core_codegen_interface->ok();
{
- BufferReader reader(buffer);
+ ProtoBufferReader reader(buffer);
if (!reader.status().ok()) {
return reader.status();
}
@@ -233,12 +91,10 @@
result = Status(StatusCode::INTERNAL, "Did not read entire message");
}
}
- g_core_codegen_interface->grpc_byte_buffer_destroy(buffer);
+ buffer->Clear();
return result;
}
-} // namespace internal
-
// this is needed so the following class does not conflict with protobuf
// serializers that utilize internal-only tools.
#ifdef GRPC_OPEN_SOURCE_PROTO
@@ -249,16 +105,13 @@
class SerializationTraits<T, typename std::enable_if<std::is_base_of<
grpc::protobuf::Message, T>::value>::type> {
public:
- static Status Serialize(const grpc::protobuf::Message& msg,
- grpc_byte_buffer** bp, bool* own_buffer) {
- return internal::GenericSerialize<internal::GrpcBufferWriter, T>(
- msg, bp, own_buffer);
+ static Status Serialize(const grpc::protobuf::Message& msg, ByteBuffer* bb,
+ bool* own_buffer) {
+ return GenericSerialize<ProtoBufferWriter, T>(msg, bb, own_buffer);
}
- static Status Deserialize(grpc_byte_buffer* buffer,
- grpc::protobuf::Message* msg) {
- return internal::GenericDeserialize<internal::GrpcBufferReader, T>(buffer,
- msg);
+ static Status Deserialize(ByteBuffer* buffer, grpc::protobuf::Message* msg) {
+ return GenericDeserialize<ProtoBufferReader, T>(buffer, msg);
}
};
#endif
diff --git a/include/grpcpp/impl/codegen/server_context.h b/include/grpcpp/impl/codegen/server_context.h
index bb357d6..bced420 100644
--- a/include/grpcpp/impl/codegen/server_context.h
+++ b/include/grpcpp/impl/codegen/server_context.h
@@ -88,8 +88,8 @@
///
/// Context settings are only relevant to the call handler they are supplied to,
/// that is to say, they aren't sticky across multiple calls. Some of these
-/// settings, such as the compression options, can be made persistant at server
-/// construction time by specifying the approriate \a ChannelArguments
+/// settings, such as the compression options, can be made persistent at server
+/// construction time by specifying the appropriate \a ChannelArguments
/// to a \a grpc::ServerBuilder, via \a ServerBuilder::AddChannelArgument.
///
/// \warning ServerContext instances should \em not be reused across rpcs.
diff --git a/include/grpcpp/impl/codegen/server_interface.h b/include/grpcpp/impl/codegen/server_interface.h
index 4700763..cf330ac 100644
--- a/include/grpcpp/impl/codegen/server_interface.h
+++ b/include/grpcpp/impl/codegen/server_interface.h
@@ -20,6 +20,7 @@
#define GRPCPP_IMPL_CODEGEN_SERVER_INTERFACE_H
#include <grpc/impl/codegen/grpc_types.h>
+#include <grpcpp/impl/codegen/byte_buffer.h>
#include <grpcpp/impl/codegen/call_hook.h>
#include <grpcpp/impl/codegen/completion_queue_tag.h>
#include <grpcpp/impl/codegen/core_codegen_interface.h>
@@ -185,14 +186,18 @@
notification_cq_(notification_cq),
tag_(tag),
request_(request) {
- IssueRequest(registered_method, &payload_, notification_cq);
+ IssueRequest(registered_method, payload_.bbuf_ptr(), notification_cq);
+ }
+
+ ~PayloadAsyncRequest() {
+ payload_.Release(); // We do not own the payload_
}
bool FinalizeResult(void** tag, bool* status) override {
if (*status) {
- if (payload_ == nullptr ||
- !SerializationTraits<Message>::Deserialize(payload_, request_)
- .ok()) {
+ if (!payload_.Valid() || !SerializationTraits<Message>::Deserialize(
+ payload_.bbuf_ptr(), request_)
+ .ok()) {
// If deserialization fails, we cancel the call and instantiate
// a new instance of ourselves to request another call. We then
// return false, which prevents the call from being returned to
@@ -219,7 +224,7 @@
ServerCompletionQueue* const notification_cq_;
void* const tag_;
Message* const request_;
- grpc_byte_buffer* payload_;
+ ByteBuffer payload_;
};
class GenericAsyncRequest : public BaseAsyncRequest {
diff --git a/include/grpcpp/impl/codegen/slice.h b/include/grpcpp/impl/codegen/slice.h
index fcccd4b..8966559 100644
--- a/include/grpcpp/impl/codegen/slice.h
+++ b/include/grpcpp/impl/codegen/slice.h
@@ -35,34 +35,43 @@
class Slice final {
public:
/// Construct an empty slice.
- Slice();
+ Slice() : slice_(g_core_codegen_interface->grpc_empty_slice()) {}
/// Destructor - drops one reference.
- ~Slice();
+ ~Slice() { g_core_codegen_interface->grpc_slice_unref(slice_); }
enum AddRef { ADD_REF };
/// Construct a slice from \a slice, adding a reference.
- Slice(grpc_slice slice, AddRef);
+ Slice(grpc_slice slice, AddRef)
+ : slice_(g_core_codegen_interface->grpc_slice_ref(slice)) {}
enum StealRef { STEAL_REF };
/// Construct a slice from \a slice, stealing a reference.
- Slice(grpc_slice slice, StealRef);
+ Slice(grpc_slice slice, StealRef) : slice_(slice) {}
/// Allocate a slice of specified size
- Slice(size_t len);
+ Slice(size_t len)
+ : slice_(g_core_codegen_interface->grpc_slice_malloc(len)) {}
/// Construct a slice from a copied buffer
- Slice(const void* buf, size_t len);
+ Slice(const void* buf, size_t len)
+ : slice_(g_core_codegen_interface->grpc_slice_from_copied_buffer(
+ reinterpret_cast<const char*>(buf), len)) {}
/// Construct a slice from a copied string
- Slice(const grpc::string& str);
+ Slice(const grpc::string& str)
+ : slice_(g_core_codegen_interface->grpc_slice_from_copied_buffer(
+ str.c_str(), str.length())) {}
enum StaticSlice { STATIC_SLICE };
/// Construct a slice from a static buffer
- Slice(const void* buf, size_t len, StaticSlice);
+ Slice(const void* buf, size_t len, StaticSlice)
+ : slice_(g_core_codegen_interface->grpc_slice_from_static_buffer(
+ reinterpret_cast<const char*>(buf), len)) {}
/// Copy constructor, adds a reference.
- Slice(const Slice& other);
+ Slice(const Slice& other)
+ : slice_(g_core_codegen_interface->grpc_slice_ref(other.slice_)) {}
/// Assignment, reference count is unchanged.
Slice& operator=(Slice other) {
@@ -75,14 +84,18 @@
/// user data pointer passed in at destruction. Can be the same as buf or
/// different (e.g., if data is part of a larger structure that must be
/// destroyed when the data is no longer needed)
- Slice(void* buf, size_t len, void (*destroy)(void*), void* user_data);
+ Slice(void* buf, size_t len, void (*destroy)(void*), void* user_data)
+ : slice_(g_core_codegen_interface->grpc_slice_new_with_user_data(
+ buf, len, destroy, user_data)) {}
/// Specialization of above for common case where buf == user_data
Slice(void* buf, size_t len, void (*destroy)(void*))
: Slice(buf, len, destroy, buf) {}
/// Similar to the above but has a destroy that also takes slice length
- Slice(void* buf, size_t len, void (*destroy)(void*, size_t));
+ Slice(void* buf, size_t len, void (*destroy)(void*, size_t))
+ : slice_(g_core_codegen_interface->grpc_slice_new_with_len(buf, len,
+ destroy)) {}
/// Byte size.
size_t size() const { return GRPC_SLICE_LENGTH(slice_); }
@@ -94,7 +107,9 @@
const uint8_t* end() const { return GRPC_SLICE_END_PTR(slice_); }
/// Raw C slice. Caller needs to call grpc_slice_unref when done.
- grpc_slice c_slice() const;
+ grpc_slice c_slice() const {
+ return g_core_codegen_interface->grpc_slice_ref(slice_);
+ }
private:
friend class ByteBuffer;
diff --git a/include/grpcpp/security/credentials.h b/include/grpcpp/security/credentials.h
index 837a0e4..36d95d1 100644
--- a/include/grpcpp/security/credentials.h
+++ b/include/grpcpp/security/credentials.h
@@ -21,6 +21,7 @@
#include <map>
#include <memory>
+#include <vector>
#include <grpcpp/impl/codegen/grpc_library.h>
#include <grpcpp/security/auth_context.h>
@@ -219,6 +220,21 @@
std::shared_ptr<CallCredentials> MetadataCredentialsFromPlugin(
std::unique_ptr<MetadataCredentialsPlugin> plugin);
+namespace experimental {
+
+/// Options used to build AltsCredentials.
+struct AltsCredentialsOptions {
+ /// service accounts of target endpoint that will be acceptable
+ /// by the client. If service accounts are provided and none of them matches
+ /// that of the server, authentication will fail.
+ std::vector<grpc::string> target_service_accounts;
+};
+
+/// Builds ALTS Credentials given ALTS specific options
+std::shared_ptr<ChannelCredentials> AltsCredentials(
+ const AltsCredentialsOptions& options);
+
+} // namespace experimental
} // namespace grpc
#endif // GRPCPP_SECURITY_CREDENTIALS_H
diff --git a/include/grpcpp/security/server_credentials.h b/include/grpcpp/security/server_credentials.h
index 892863e..cf57e27 100644
--- a/include/grpcpp/security/server_credentials.h
+++ b/include/grpcpp/security/server_credentials.h
@@ -86,6 +86,18 @@
/// Builds insecure server credentials.
std::shared_ptr<ServerCredentials> InsecureServerCredentials();
+namespace experimental {
+
+/// Options to create ServerCredentials with ALTS
+struct AltsServerCredentialsOptions {
+ /// Add fields if needed.
+};
+
+/// Builds ALTS ServerCredentials given ALTS specific options
+std::shared_ptr<ServerCredentials> AltsServerCredentials(
+ const AltsServerCredentialsOptions& options);
+
+} // namespace experimental
} // namespace grpc
#endif // GRPCPP_SECURITY_SERVER_CREDENTIALS_H
diff --git a/include/grpcpp/support/channel_arguments.h b/include/grpcpp/support/channel_arguments.h
index 1eead4e..217929d 100644
--- a/include/grpcpp/support/channel_arguments.h
+++ b/include/grpcpp/support/channel_arguments.h
@@ -70,7 +70,13 @@
/// the resolver.
void SetGrpclbFallbackTimeout(int fallback_timeout);
- /// Set the socket mutator for the channel.
+ /// For client channel's, the socket mutator operates on
+ /// "channel" sockets. For server's, the socket mutator operates
+ /// only on "listen" sockets.
+ /// TODO(apolcyn): allow socket mutators to also operate
+ /// on server "channel" sockets, and adjust the socket mutator
+ /// object to be more speficic about which type of socket
+ /// it should operate on.
void SetSocketMutator(grpc_socket_mutator* mutator);
/// Set the string to prepend to the user agent.
diff --git a/include/grpcpp/support/proto_buffer_reader.h b/include/grpcpp/support/proto_buffer_reader.h
new file mode 100644
index 0000000..4cdb65d
--- /dev/null
+++ b/include/grpcpp/support/proto_buffer_reader.h
@@ -0,0 +1,24 @@
+/*
+ *
+ * Copyright 2018 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 GRPCPP_SUPPORT_PROTO_BUFFER_READER_H
+#define GRPCPP_SUPPORT_PROTO_BUFFER_READER_H
+
+#include <grpcpp/impl/codegen/proto_buffer_reader.h>
+
+#endif // GRPCPP_SUPPORT_PROTO_BUFFER_READER_H
diff --git a/include/grpcpp/support/proto_buffer_writer.h b/include/grpcpp/support/proto_buffer_writer.h
new file mode 100644
index 0000000..01cf29c
--- /dev/null
+++ b/include/grpcpp/support/proto_buffer_writer.h
@@ -0,0 +1,24 @@
+/*
+ *
+ * Copyright 2018 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 GRPCPP_SUPPORT_PROTO_BUFFER_WRITER_H
+#define GRPCPP_SUPPORT_PROTO_BUFFER_WRITER_H
+
+#include <grpcpp/impl/codegen/proto_buffer_writer.h>
+
+#endif // GRPCPP_SUPPORT_PROTO_BUFFER_WRITER_H
diff --git a/package.xml b/package.xml
index 52d5cc9..ac9b520 100644
--- a/package.xml
+++ b/package.xml
@@ -13,8 +13,8 @@
<date>2018-01-19</date>
<time>16:06:07</time>
<version>
- <release>1.11.0dev</release>
- <api>1.11.0dev</api>
+ <release>1.13.0dev</release>
+ <api>1.13.0dev</api>
</version>
<stability>
<release>beta</release>
@@ -208,6 +208,7 @@
<file baseinstalldir="/" name="src/core/ext/filters/http/client/http_client_filter.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/http/message_compress/message_compress_filter.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/http/server/http_server_filter.h" role="src" />
+ <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/context/security_context.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/alts/alts_credentials.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/composite/composite_credentials.h" role="src" />
@@ -259,8 +260,8 @@
<file baseinstalldir="/" name="third_party/nanopb/pb_decode.h" role="src" />
<file baseinstalldir="/" name="third_party/nanopb/pb_encode.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/transport_security.h" role="src" />
- <file baseinstalldir="/" name="src/core/tsi/transport_security_adapter.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/transport_security_interface.h" role="src" />
+ <file baseinstalldir="/" name="src/core/ext/transport/chttp2/client/authority.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/client/chttp2_connector.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/backup_poller.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/client_channel.h" role="src" />
@@ -438,6 +439,7 @@
<file baseinstalldir="/" name="src/core/ext/filters/load_reporting/server_load_reporting_plugin.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/max_age/max_age_filter.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/message_size/message_size_filter.h" role="src" />
+ <file baseinstalldir="/" name="src/core/ext/filters/http/client_authority_filter.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/workarounds/workaround_cronet_compression_filter.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/workarounds/workaround_utils.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/surface/init.cc" role="src" />
@@ -679,9 +681,9 @@
<file baseinstalldir="/" name="third_party/nanopb/pb_decode.c" role="src" />
<file baseinstalldir="/" name="third_party/nanopb/pb_encode.c" role="src" />
<file baseinstalldir="/" name="src/core/tsi/transport_security.cc" role="src" />
- <file baseinstalldir="/" name="src/core/tsi/transport_security_adapter.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/client/insecure/channel_create.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc" role="src" />
+ <file baseinstalldir="/" name="src/core/ext/transport/chttp2/client/authority.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/client/chttp2_connector.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/backup_poller.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/channel_connectivity.cc" role="src" />
@@ -726,7 +728,6 @@
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc" role="src" />
- <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc" role="src" />
@@ -739,6 +740,7 @@
<file baseinstalldir="/" name="src/core/ext/census/grpc_context.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/max_age/max_age_filter.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/message_size/message_size_filter.cc" role="src" />
+ <file baseinstalldir="/" name="src/core/ext/filters/http/client_authority_filter.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/workarounds/workaround_utils.cc" role="src" />
<file baseinstalldir="/" name="src/core/plugin_registry/grpc_plugin_registry.cc" role="src" />
diff --git a/setup.py b/setup.py
index 97a3107..99d1a1c 100644
--- a/setup.py
+++ b/setup.py
@@ -104,9 +104,9 @@
EXTRA_ENV_COMPILE_ARGS = os.environ.get('GRPC_PYTHON_CFLAGS', None)
EXTRA_ENV_LINK_ARGS = os.environ.get('GRPC_PYTHON_LDFLAGS', None)
if EXTRA_ENV_COMPILE_ARGS is None:
- EXTRA_ENV_COMPILE_ARGS = ''
+ EXTRA_ENV_COMPILE_ARGS = ' -std=c++11'
if 'win32' in sys.platform and sys.version_info < (3, 5):
- EXTRA_ENV_COMPILE_ARGS += ' -std=c++11'
+ EXTRA_ENV_COMPILE_ARGS += ' -D_hypot=hypot'
# We use define flags here and don't directly add to DEFINE_MACROS below to
# ensure that the expert user/builder has a way of turning it off (via the
# envvars) without adding yet more GRPC-specific envvars.
@@ -116,10 +116,10 @@
else:
EXTRA_ENV_COMPILE_ARGS += ' -D_ftime=_ftime64 -D_timeb=__timeb64'
elif "linux" in sys.platform:
- EXTRA_ENV_COMPILE_ARGS += ' -std=c++11 -std=gnu99 -fvisibility=hidden -fno-wrapv -fno-exceptions'
+ EXTRA_ENV_COMPILE_ARGS += ' -std=gnu99 -fvisibility=hidden -fno-wrapv -fno-exceptions'
elif "darwin" in sys.platform:
EXTRA_ENV_COMPILE_ARGS += ' -fvisibility=hidden -fno-wrapv -fno-exceptions'
-EXTRA_ENV_COMPILE_ARGS += ' -DPB_FIELD_16BIT'
+EXTRA_ENV_COMPILE_ARGS += ' -DPB_FIELD_16BIT'
if EXTRA_ENV_LINK_ARGS is None:
EXTRA_ENV_LINK_ARGS = ''
@@ -182,7 +182,7 @@
CFLAGS = tuple(EXTRA_COMPILE_ARGS)
if "linux" in sys.platform or "darwin" in sys.platform:
pymodinit_type = 'PyObject*' if PY3 else 'void'
- pymodinit = '__attribute__((visibility ("default"))) {}'.format(pymodinit_type)
+ pymodinit = 'extern "C" __attribute__((visibility ("default"))) {}'.format(pymodinit_type)
DEFINE_MACROS += (('PyMODINIT_FUNC', pymodinit),)
DEFINE_MACROS += (('GRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK', 1),)
@@ -239,9 +239,6 @@
INSTALL_REQUIRES = (
'six>=1.5.2',
- # TODO(atash): eventually split the grpcio package into a metapackage
- # depending on protobuf and the runtime component (independent of protobuf)
- 'protobuf>=3.5.0.post1',
)
if not PY3:
diff --git a/src/android/test/interop/.gitignore b/src/android/test/interop/.gitignore
new file mode 100644
index 0000000..39fb081
--- /dev/null
+++ b/src/android/test/interop/.gitignore
@@ -0,0 +1,9 @@
+*.iml
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
+.externalNativeBuild
diff --git a/src/android/test/interop/README.md b/src/android/test/interop/README.md
new file mode 100644
index 0000000..9526230
--- /dev/null
+++ b/src/android/test/interop/README.md
@@ -0,0 +1,37 @@
+gRPC on Android
+==============
+
+Note: Building the protobuf dependency for Android requires
+https://github.com/google/protobuf/pull/3878. This fix will be in the next
+protobuf release, but until then must be manually patched in to
+`third_party/protobuf` to build gRPC for Android.
+
+PREREQUISITES
+-------------
+
+- Android SDK
+- Android NDK
+- `protoc` and `grpc_cpp_plugin` binaries on the host system
+
+INSTALL
+-------
+
+The example application can be built via Android Studio or on the command line
+using `gradle`:
+
+ ```sh
+ $ ./gradlew installDebug
+ ```
+
+INSTRUMENTATION TESTS
+---------------------
+
+The instrumentation tests can be run via the following `gradle` command. This
+requires an emulator already running on your computer.
+
+```
+$ ./gradlew connectedAndroidTest \
+ -Pandroid.testInstrumentationRunnerArguments.server_host=grpc-test.sandbox.googleapis.com \
+ -Pandroid.testInstrumentationRunnerArguments.server_port=443 \
+ -Pandroid.testInstrumentationRunnerArguments.use_tls=true
+```
diff --git a/src/android/test/interop/app/.gitignore b/src/android/test/interop/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/src/android/test/interop/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/src/android/test/interop/app/CMakeLists.txt b/src/android/test/interop/app/CMakeLists.txt
new file mode 100644
index 0000000..092995f
--- /dev/null
+++ b/src/android/test/interop/app/CMakeLists.txt
@@ -0,0 +1,119 @@
+cmake_minimum_required(VERSION 3.4.1)
+
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
+
+set(PROTOBUF_PROTOC_EXECUTABLE "/usr/local/bin/protoc" CACHE STRING "Protoc binary on host")
+set(gRPC_CPP_PLUGIN_EXECUTABLE "/usr/local/bin/grpc_cpp_plugin" CACHE STRING "gRPC CPP plugin binary on host")
+
+set(GRPC_SRC_DIR ../../../../../)
+
+set(GRPC_BUILD_DIR ../grpc/outputs/${ANDROID_ABI})
+file(MAKE_DIRECTORY ${GRPC_BUILD_DIR})
+
+add_subdirectory(${GRPC_SRC_DIR} ${GRPC_BUILD_DIR})
+
+#include_directories(${GRPC_SRC_DIR}/include)
+include_directories(${GRPC_SRC_DIR})
+
+set(GRPC_PROTO_GENS_DIR ${CMAKE_BINARY_DIR}/gens)
+file(MAKE_DIRECTORY ${GRPC_PROTO_GENS_DIR})
+include_directories(${GRPC_PROTO_GENS_DIR})
+
+function(android_protobuf_grpc_generate_cpp SRC_FILES HDR_FILES INCLUDE_ROOT)
+ if(NOT ARGN)
+ message(SEND_ERROR "Error: android_protobuf_grpc_generate_cpp() called without any proto files")
+ return()
+ endif()
+
+ set(${SRC_FILES})
+ set(${HDR_FILES})
+ set(PROTOBUF_INCLUDE_PATH -I ${INCLUDE_ROOT})
+ foreach(FIL ${ARGN})
+ get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
+ get_filename_component(FIL_WE ${FIL} NAME_WE)
+ file(RELATIVE_PATH REL_FIL ${CMAKE_CURRENT_SOURCE_DIR}/${INCLUDE_ROOT} ${ABS_FIL})
+ get_filename_component(REL_DIR ${REL_FIL} DIRECTORY)
+ set(RELFIL_WE "${REL_DIR}/${FIL_WE}")
+
+ list(APPEND ${SRC_FILES} "${GRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.cc")
+ list(APPEND ${HDR_FILES} "${GRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.h")
+ list(APPEND ${SRC_FILES} "${GRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.cc")
+ list(APPEND ${HDR_FILES} "${GRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.h")
+
+ add_custom_command(
+ OUTPUT "${GRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.cc"
+ "${GRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.h"
+ "${GRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.cc"
+ "${GRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.h"
+ COMMAND ${PROTOBUF_PROTOC_EXECUTABLE}
+ ARGS --grpc_out=${GRPC_PROTO_GENS_DIR}
+ --cpp_out=${GRPC_PROTO_GENS_DIR}
+ --plugin=protoc-gen-grpc=${gRPC_CPP_PLUGIN_EXECUTABLE}
+ ${PROTOBUF_INCLUDE_PATH}
+ ${REL_FIL}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ DEPENDS ${PROTOBUF_PROTOC_EXECUTABLE} ${gRPC_CPP_PLUGIN_EXECUTABLE} ${ABS_FIL} )
+ endforeach()
+
+ set_source_files_properties(${${SRC_FILES}} ${${HDR_FILES}} PROPERTIES GENERATED TRUE)
+ set(${SRC_FILES} ${${SRC_FILES}} PARENT_SCOPE)
+ set(${HDR_FILES} ${${HDR_FILES}} PARENT_SCOPE)
+endfunction()
+
+set(PROTO_BASE_DIR ${GRPC_SRC_DIR}/examples/protos)
+
+android_protobuf_grpc_generate_cpp(
+ MESSAGES_PROTO_SRCS MESSAGES_PROTO_HDRS
+ ${GRPC_SRC_DIR} ${GRPC_SRC_DIR}/src/proto/grpc/testing/messages.proto)
+
+add_library(messages_proto_lib
+ SHARED ${MESSAGES_PROTO_SRCS} ${MESSAGES_PROTO_HDRS})
+
+target_link_libraries(messages_proto_lib
+ libprotobuf
+ grpc++
+ android
+ log)
+
+android_protobuf_grpc_generate_cpp(
+ EMPTY_PROTO_SRCS EMPTY_PROTO_HDRS
+ ${GRPC_SRC_DIR} ${GRPC_SRC_DIR}/src/proto/grpc/testing/empty.proto)
+
+add_library(empty_proto_lib
+ SHARED ${EMPTY_PROTO_SRCS} ${EMPTY_PROTO_HDRS})
+
+target_link_libraries(empty_proto_lib
+ libprotobuf
+ grpc++
+ android
+ log)
+
+android_protobuf_grpc_generate_cpp(
+ TEST_PROTO_SRCS TEST_PROTO_HDRS ${GRPC_SRC_DIR} ${GRPC_SRC_DIR}/src/proto/grpc/testing/test.proto)
+
+add_library(test_proto_lib
+ SHARED ${TEST_PROTO_SRCS} ${TEST_PROTO_HDRS})
+
+target_link_libraries(test_proto_lib
+ libprotobuf
+ grpc++
+ empty_proto_lib
+ messages_proto_lib
+ android
+ log)
+
+find_library(log-lib
+ log)
+
+add_library(grpc-interop
+ SHARED
+ src/main/cpp/grpc-interop.cc
+ ${GRPC_SRC_DIR}/test/cpp/interop/interop_client.h
+ ${GRPC_SRC_DIR}/test/cpp/interop/interop_client.cc)
+
+target_link_libraries(grpc-interop
+ messages_proto_lib
+ empty_proto_lib
+ test_proto_lib
+ android
+ ${log-lib})
diff --git a/src/android/test/interop/app/build.gradle b/src/android/test/interop/app/build.gradle
new file mode 100644
index 0000000..2f58b99
--- /dev/null
+++ b/src/android/test/interop/app/build.gradle
@@ -0,0 +1,56 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 26
+ defaultConfig {
+ applicationId "io.grpc.android.interop.cpp"
+ minSdkVersion 14
+ targetSdkVersion 26
+ versionCode 1
+ versionName "1.0"
+ testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ externalNativeBuild {
+ cmake {
+ // The paths to the protoc and grpc_cpp_plugin binaries on the host system (codegen
+ // is not cross-compiled to Android)
+ def protoc = project.hasProperty('protoc') ?
+ project.property('protoc') : '/usr/local/bin/protoc'
+ def grpc_cpp_plugin = project.hasProperty('grpc_cpp_plugin') ?
+ project.property('grpc_cpp_plugin') : '/usr/local/bin/grpc_cpp_plugin'
+
+ cppFlags "-std=c++14 -frtti -fexceptions"
+ arguments '-DANDROID_STL=c++_shared'
+ arguments '-DRUN_HAVE_POSIX_REGEX=0'
+ arguments '-DRUN_HAVE_STD_REGEX=0'
+ arguments '-DRUN_HAVE_STEADY_CLOCK=0'
+ arguments '-Dprotobuf_BUILD_PROTOC_BINARIES=off'
+ arguments '-DgRPC_BUILD_CODEGEN=off'
+ arguments '-DPROTOBUF_PROTOC_EXECUTABLE=' + protoc
+ arguments '-DgRPC_CPP_PLUGIN_EXECUTABLE=' + grpc_cpp_plugin
+ }
+ }
+ ndk.abiFilters 'x86'
+ }
+ buildTypes {
+ debug {
+ minifyEnabled false
+ }
+ release {
+ minifyEnabled true
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+ externalNativeBuild {
+ cmake {
+ path "CMakeLists.txt"
+ }
+ }
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation 'com.android.support:appcompat-v7:26.1.0'
+ testImplementation 'junit:junit:4.12'
+ androidTestImplementation 'com.android.support.test:runner:1.0.1'
+ androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
+}
diff --git a/src/android/test/interop/app/proguard-rules.pro b/src/android/test/interop/app/proguard-rules.pro
new file mode 100644
index 0000000..f1b4245
--- /dev/null
+++ b/src/android/test/interop/app/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/src/android/test/interop/app/src/androidTest/java/io/grpc/interop/cpp/InteropTest.java b/src/android/test/interop/app/src/androidTest/java/io/grpc/interop/cpp/InteropTest.java
new file mode 100644
index 0000000..d1bc259
--- /dev/null
+++ b/src/android/test/interop/app/src/androidTest/java/io/grpc/interop/cpp/InteropTest.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2018, gRPC Authors All rights reserved.
+ *
+ * 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.
+ */
+
+package io.grpc.interop.cpp;
+
+import static junit.framework.Assert.assertTrue;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class InteropTest {
+ private String host;
+ private int port;
+ private boolean useTls;
+
+ @Before
+ public void setUp() throws Exception {
+ host =
+ InstrumentationRegistry.getArguments()
+ .getString("server_host", "grpc-test.sandbox.googleapis.com");
+ port = Integer.parseInt(InstrumentationRegistry.getArguments().getString("server_port", "443"));
+ useTls =
+ Boolean.parseBoolean(InstrumentationRegistry.getArguments().getString("use_tls", "true"));
+
+ if (useTls) {
+ Context ctx = InstrumentationRegistry.getTargetContext();
+ String sslRootsFile = "roots.pem";
+ InputStream in = ctx.getAssets().open(sslRootsFile);
+ File outFile = new File(ctx.getExternalFilesDir(null), sslRootsFile);
+ OutputStream out = new FileOutputStream(outFile);
+ byte[] buffer = new byte[1024];
+ int bytesRead;
+ while ((bytesRead = in.read(buffer)) != -1) {
+ out.write(buffer, 0, bytesRead);
+ }
+ in.close();
+ out.close();
+ InteropActivity.configureSslRoots(outFile.getCanonicalPath());
+ }
+ }
+
+ @Test
+ public void emptyUnary() {
+ assertTrue(InteropActivity.doEmpty(host, port, useTls));
+ }
+
+ @Test
+ public void largeUnary() {
+ assertTrue(InteropActivity.doLargeUnary(host, port, useTls));
+ }
+
+ @Test
+ public void emptyStream() {
+ assertTrue(InteropActivity.doEmptyStream(host, port, useTls));
+ }
+
+ @Test
+ public void requestStreaming() {
+ assertTrue(InteropActivity.doRequestStreaming(host, port, useTls));
+ }
+
+ @Test
+ public void responseStreaming() {
+ assertTrue(InteropActivity.doResponseStreaming(host, port, useTls));
+ }
+
+ @Test
+ public void pingPong() {
+ assertTrue(InteropActivity.doPingPong(host, port, useTls));
+ }
+}
diff --git a/src/android/test/interop/app/src/main/AndroidManifest.xml b/src/android/test/interop/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..009112a
--- /dev/null
+++ b/src/android/test/interop/app/src/main/AndroidManifest.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="io.grpc.interop.cpp" >
+
+ <uses-permission android:name="android.permission.INTERNET" />
+
+ <application
+ android:allowBackup="false"
+ android:icon="@mipmap/ic_launcher"
+ android:label="@string/app_name"
+ android:theme="@style/Base.V7.Theme.AppCompat.Light" >
+ <activity
+ android:name=".InteropActivity"
+ android:label="@string/app_name" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
diff --git a/src/android/test/interop/app/src/main/assets/roots.pem b/src/android/test/interop/app/src/main/assets/roots.pem
new file mode 100644
index 0000000..15d819b
--- /dev/null
+++ b/src/android/test/interop/app/src/main/assets/roots.pem
@@ -0,0 +1,4475 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+# Issuer: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA
+# Subject: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA
+# Label: "GlobalSign Root CA"
+# Serial: 4835703278459707669005204
+# MD5 Fingerprint: 3e:45:52:15:09:51:92:e1:b7:5d:37:9f:b1:87:29:8a
+# SHA1 Fingerprint: b1:bc:96:8b:d4:f4:9d:62:2a:a8:9a:81:f2:15:01:52:a4:1d:82:9c
+# SHA256 Fingerprint: eb:d4:10:40:e4:bb:3e:c7:42:c9:e3:81:d3:1e:f2:a4:1a:48:b6:68:5c:96:e7:ce:f3:c1:df:6c:d4:33:1c:99
+-----BEGIN CERTIFICATE-----
+MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG
+A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv
+b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw
+MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i
+YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT
+aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ
+jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp
+xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp
+1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG
+snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ
+U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8
+9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E
+BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B
+AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz
+yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE
+38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP
+AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad
+DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME
+HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==
+-----END CERTIFICATE-----
+
+# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2
+# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2
+# Label: "GlobalSign Root CA - R2"
+# Serial: 4835703278459682885658125
+# MD5 Fingerprint: 94:14:77:7e:3e:5e:fd:8f:30:bd:41:b0:cf:e7:d0:30
+# SHA1 Fingerprint: 75:e0:ab:b6:13:85:12:27:1c:04:f8:5f:dd:de:38:e4:b7:24:2e:fe
+# SHA256 Fingerprint: ca:42:dd:41:74:5f:d0:b8:1e:b9:02:36:2c:f9:d8:bf:71:9d:a1:bd:1b:1e:fc:94:6f:5b:4c:99:f4:2c:1b:9e
+-----BEGIN CERTIFICATE-----
+MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G
+A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp
+Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1
+MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG
+A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL
+v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8
+eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq
+tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd
+C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa
+zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB
+mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH
+V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n
+bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG
+3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs
+J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO
+291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS
+ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd
+AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7
+TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==
+-----END CERTIFICATE-----
+
+# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only
+# Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only
+# Label: "Verisign Class 3 Public Primary Certification Authority - G3"
+# Serial: 206684696279472310254277870180966723415
+# MD5 Fingerprint: cd:68:b6:a7:c7:c4:ce:75:e0:1d:4f:57:44:61:92:09
+# SHA1 Fingerprint: 13:2d:0d:45:53:4b:69:97:cd:b2:d5:c3:39:e2:55:76:60:9b:5c:c6
+# SHA256 Fingerprint: eb:04:cf:5e:b1:f3:9a:fa:76:2f:2b:b1:20:f2:96:cb:a5:20:c1:b9:7d:b1:58:95:65:b8:1c:b9:a1:7b:72:44
+-----BEGIN CERTIFICATE-----
+MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQsw
+CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl
+cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu
+LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT
+aWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
+dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD
+VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT
+aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ
+bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu
+IENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg
+LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMu6nFL8eB8aHm8b
+N3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1EUGO+i2t
+KmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGu
+kxUccLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBm
+CC+Vk7+qRy+oRpfwEuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJ
+Xwzw3sJ2zq/3avL6QaaiMxTJ5Xpj055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWu
+imi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAERSWwauSCPc/L8my/uRan2Te
+2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5fj267Cz3qWhMe
+DGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC
+/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565p
+F4ErWjfJXir0xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGt
+TxzhT5yvDwyd93gN2PQ1VoDat20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ==
+-----END CERTIFICATE-----
+
+# Issuer: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited
+# Subject: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited
+# Label: "Entrust.net Premium 2048 Secure Server CA"
+# Serial: 946069240
+# MD5 Fingerprint: ee:29:31:bc:32:7e:9a:e6:e8:b5:f7:51:b4:34:71:90
+# SHA1 Fingerprint: 50:30:06:09:1d:97:d4:f5:ae:39:f7:cb:e7:92:7d:7d:65:2d:34:31
+# SHA256 Fingerprint: 6d:c4:71:72:e0:1c:bc:b0:bf:62:58:0d:89:5f:e2:b8:ac:9a:d4:f8:73:80:1e:0c:10:b9:c8:37:d2:1e:b1:77
+-----BEGIN CERTIFICATE-----
+MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML
+RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp
+bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5
+IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp
+ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0yOTA3
+MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3
+LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp
+YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG
+A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq
+K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe
+sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX
+MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT
+XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/
+HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH
+4QIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV
+HQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJKoZIhvcNAQEFBQADggEBADub
+j1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPyT/4xmf3IDExo
+U8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf
+zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5b
+u/8j72gZyxKTJ1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+
+bYQLCIt+jerXmCHG8+c8eS9enNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/Er
+fF6adulZkMV8gzURZVE=
+-----END CERTIFICATE-----
+
+# Issuer: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust
+# Subject: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust
+# Label: "Baltimore CyberTrust Root"
+# Serial: 33554617
+# MD5 Fingerprint: ac:b6:94:a5:9c:17:e0:d7:91:52:9b:b1:97:06:a6:e4
+# SHA1 Fingerprint: d4:de:20:d0:5e:66:fc:53:fe:1a:50:88:2c:78:db:28:52:ca:e4:74
+# SHA256 Fingerprint: 16:af:57:a9:f6:76:b0:ab:12:60:95:aa:5e:ba:de:f2:2a:b3:11:19:d6:44:ac:95:cd:4b:93:db:f3:f2:6a:eb
+-----BEGIN CERTIFICATE-----
+MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ
+RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD
+VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX
+DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y
+ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy
+VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr
+mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr
+IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK
+mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu
+XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy
+dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye
+jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1
+BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3
+DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92
+9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx
+jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0
+Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz
+ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS
+R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
+-----END CERTIFICATE-----
+
+# Issuer: CN=AddTrust External CA Root O=AddTrust AB OU=AddTrust External TTP Network
+# Subject: CN=AddTrust External CA Root O=AddTrust AB OU=AddTrust External TTP Network
+# Label: "AddTrust External Root"
+# Serial: 1
+# MD5 Fingerprint: 1d:35:54:04:85:78:b0:3f:42:42:4d:bf:20:73:0a:3f
+# SHA1 Fingerprint: 02:fa:f3:e2:91:43:54:68:60:78:57:69:4d:f5:e4:5b:68:85:18:68
+# SHA256 Fingerprint: 68:7f:a4:51:38:22:78:ff:f0:c8:b1:1f:8d:43:d5:76:67:1c:6e:b2:bc:ea:b4:13:fb:83:d9:65:d0:6d:2f:f2
+-----BEGIN CERTIFICATE-----
+MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU
+MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs
+IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290
+MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux
+FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h
+bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v
+dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt
+H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9
+uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX
+mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX
+a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN
+E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0
+WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD
+VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0
+Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU
+cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx
+IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN
+AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH
+YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5
+6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC
+Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX
+c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a
+mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=
+-----END CERTIFICATE-----
+
+# Issuer: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc.
+# Subject: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc.
+# Label: "Entrust Root Certification Authority"
+# Serial: 1164660820
+# MD5 Fingerprint: d6:a5:c3:ed:5d:dd:3e:00:c1:3d:87:92:1f:1d:3f:e4
+# SHA1 Fingerprint: b3:1e:b1:b7:40:e3:6c:84:02:da:dc:37:d4:4d:f5:d4:67:49:52:f9
+# SHA256 Fingerprint: 73:c1:76:43:4f:1b:c6:d5:ad:f4:5b:0e:76:e7:27:28:7c:8d:e5:76:16:c1:e6:e6:14:1a:2b:2c:bc:7d:8e:4c
+-----BEGIN CERTIFICATE-----
+MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC
+VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0
+Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW
+KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl
+cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw
+NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw
+NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy
+ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV
+BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ
+KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo
+Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4
+4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9
+KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI
+rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi
+94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB
+sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi
+gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo
+kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE
+vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA
+A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t
+O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua
+AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP
+9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/
+eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m
+0vdXcDazv/wor3ElhVsT/h5/WrQ8
+-----END CERTIFICATE-----
+
+# Issuer: CN=GeoTrust Global CA O=GeoTrust Inc.
+# Subject: CN=GeoTrust Global CA O=GeoTrust Inc.
+# Label: "GeoTrust Global CA"
+# Serial: 144470
+# MD5 Fingerprint: f7:75:ab:29:fb:51:4e:b7:77:5e:ff:05:3c:99:8e:f5
+# SHA1 Fingerprint: de:28:f4:a4:ff:e5:b9:2f:a3:c5:03:d1:a3:49:a7:f9:96:2a:82:12
+# SHA256 Fingerprint: ff:85:6a:2d:25:1d:cd:88:d3:66:56:f4:50:12:67:98:cf:ab:aa:de:40:79:9c:72:2d:e4:d2:b5:db:36:a7:3a
+-----BEGIN CERTIFICATE-----
+MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
+MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
+YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG
+EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg
+R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9
+9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq
+fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv
+iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU
+1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+
+bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW
+MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA
+ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l
+uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn
+Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS
+tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF
+PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un
+hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV
+5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw==
+-----END CERTIFICATE-----
+
+# Issuer: CN=GeoTrust Universal CA O=GeoTrust Inc.
+# Subject: CN=GeoTrust Universal CA O=GeoTrust Inc.
+# Label: "GeoTrust Universal CA"
+# Serial: 1
+# MD5 Fingerprint: 92:65:58:8b:a2:1a:31:72:73:68:5c:b4:a5:7a:07:48
+# SHA1 Fingerprint: e6:21:f3:35:43:79:05:9a:4b:68:30:9d:8a:2f:74:22:15:87:ec:79
+# SHA256 Fingerprint: a0:45:9b:9f:63:b2:25:59:f5:fa:5d:4c:6d:b3:f9:f7:2f:f1:93:42:03:35:78:f0:73:bf:1d:1b:46:cb:b9:12
+-----BEGIN CERTIFICATE-----
+MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEW
+MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVy
+c2FsIENBMB4XDTA0MDMwNDA1MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UE
+BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xHjAcBgNVBAMTFUdlb1RydXN0
+IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKYV
+VaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9tJPi8
+cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTT
+QjOgNB0eRXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFh
+F7em6fgemdtzbvQKoiFs7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2v
+c7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d8Lsrlh/eezJS/R27tQahsiFepdaVaH/w
+mZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7VqnJNk22CDtucvc+081xd
+VHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3CgaRr0BHdCX
+teGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZ
+f9hBZ3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfRe
+Bi9Fi1jUIxaS5BZuKGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+
+nhutxx9z3SxPGWX9f5NAEC7S8O08ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB
+/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0XG0D08DYj3rWMB8GA1UdIwQY
+MBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG
+9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc
+aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fX
+IwjhmF7DWgh2qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzyn
+ANXH/KttgCJwpQzgXQQpAvvLoJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0z
+uzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsKxr2EoyNB3tZ3b4XUhRxQ4K5RirqN
+Pnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxFKyDuSN/n3QmOGKja
+QI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2DFKW
+koRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9
+ER/frslKxfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQt
+DF4JbAiXfKM9fJP/P6EUp8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/Sfuvm
+bJxPgWp6ZKy7PtXny3YuxadIwVyQD8vIP/rmMuGNG2+k5o7Y+SlIis5z/iw=
+-----END CERTIFICATE-----
+
+# Issuer: CN=GeoTrust Universal CA 2 O=GeoTrust Inc.
+# Subject: CN=GeoTrust Universal CA 2 O=GeoTrust Inc.
+# Label: "GeoTrust Universal CA 2"
+# Serial: 1
+# MD5 Fingerprint: 34:fc:b8:d0:36:db:9e:14:b3:c2:f2:db:8f:e4:94:c7
+# SHA1 Fingerprint: 37:9a:19:7b:41:85:45:35:0c:a6:03:69:f3:3c:2e:af:47:4f:20:79
+# SHA256 Fingerprint: a0:23:4f:3b:c8:52:7c:a5:62:8e:ec:81:ad:5d:69:89:5d:a5:68:0d:c9:1d:1c:b8:47:7f:33:f8:78:b9:5b:0b
+-----BEGIN CERTIFICATE-----
+MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEW
+MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVy
+c2FsIENBIDIwHhcNMDQwMzA0MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYD
+VQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1
+c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
+AQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0DE81
+WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUG
+FF+3Qs17j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdq
+XbboW0W63MOhBW9Wjo8QJqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxL
+se4YuU6W3Nx2/zu+z18DwPw76L5GG//aQMJS9/7jOvdqdzXQ2o3rXhhqMcceujwb
+KNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2WP0+GfPtDCapkzj4T8Fd
+IgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP20gaXT73
+y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRt
+hAAnZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgoc
+QIgfksILAAX/8sgCSqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4
+Lt1ZrtmhN79UNdxzMk+MBB4zsslG8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNV
+HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAfBgNV
+HSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8EBAMCAYYwDQYJ
+KoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z
+dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQ
+L1EuxBRa3ugZ4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgr
+Fg5fNuH8KrUwJM/gYwx7WBr+mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSo
+ag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpqA1Ihn0CoZ1Dy81of398j9tx4TuaY
+T1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpgY+RdM4kX2TGq2tbz
+GDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiPpm8m
+1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJV
+OCiNUW7dFGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH
+6aLcr34YEoP9VhdBLtUpgn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwX
+QMAJKOSLakhT2+zNVVXxxvjpoixMptEmX36vWkzaH6byHCx+rgIW0lbQL1dTR+iS
+-----END CERTIFICATE-----
+
+# Issuer: CN=Visa eCommerce Root O=VISA OU=Visa International Service Association
+# Subject: CN=Visa eCommerce Root O=VISA OU=Visa International Service Association
+# Label: "Visa eCommerce Root"
+# Serial: 25952180776285836048024890241505565794
+# MD5 Fingerprint: fc:11:b8:d8:08:93:30:00:6d:23:f9:7e:eb:52:1e:02
+# SHA1 Fingerprint: 70:17:9b:86:8c:00:a4:fa:60:91:52:22:3f:9f:3e:32:bd:e0:05:62
+# SHA256 Fingerprint: 69:fa:c9:bd:55:fb:0a:c7:8d:53:bb:ee:5c:f1:d5:97:98:9f:d0:aa:ab:20:a2:51:51:bd:f1:73:3e:e7:d1:22
+-----BEGIN CERTIFICATE-----
+MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBr
+MQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRl
+cm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv
+bW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2WhcNMjIwNjI0MDAxNjEyWjBrMQsw
+CQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5h
+dGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1l
+cmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h
+2mCxlCfLF9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4E
+lpF7sDPwsRROEW+1QK8bRaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdV
+ZqW1LS7YgFmypw23RuwhY/81q6UCzyr0TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq
+299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI/k4+oKsGGelT84ATB+0t
+vz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzsGHxBvfaL
+dXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD
+AgEGMB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUF
+AAOCAQEAX/FBfXxcCLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcR
+zCSs00Rsca4BIGsDoo8Ytyk6feUWYFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3
+LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pzzkWKsKZJ/0x9nXGIxHYdkFsd
+7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBuYQa7FkKMcPcw
+++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt
+398znM/jra6O1I7mT1GvFpLgXPYHDw==
+-----END CERTIFICATE-----
+
+# Issuer: CN=AAA Certificate Services O=Comodo CA Limited
+# Subject: CN=AAA Certificate Services O=Comodo CA Limited
+# Label: "Comodo AAA Services root"
+# Serial: 1
+# MD5 Fingerprint: 49:79:04:b0:eb:87:19:ac:47:b0:bc:11:51:9b:74:d0
+# SHA1 Fingerprint: d1:eb:23:a4:6d:17:d6:8f:d9:25:64:c2:f1:f1:60:17:64:d8:e3:49
+# SHA256 Fingerprint: d7:a7:a0:fb:5d:7e:27:31:d7:71:e9:48:4e:bc:de:f7:1d:5f:0c:3e:0a:29:48:78:2b:c8:3e:e0:ea:69:9e:f4
+-----BEGIN CERTIFICATE-----
+MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb
+MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
+GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj
+YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL
+MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE
+BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM
+GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua
+BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe
+3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4
+YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR
+rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm
+ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU
+oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF
+MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v
+QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t
+b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF
+AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q
+GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz
+Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2
+G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi
+l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3
+smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==
+-----END CERTIFICATE-----
+
+# Issuer: CN=QuoVadis Root Certification Authority O=QuoVadis Limited OU=Root Certification Authority
+# Subject: CN=QuoVadis Root Certification Authority O=QuoVadis Limited OU=Root Certification Authority
+# Label: "QuoVadis Root CA"
+# Serial: 985026699
+# MD5 Fingerprint: 27:de:36:fe:72:b7:00:03:00:9d:f4:f0:1e:6c:04:24
+# SHA1 Fingerprint: de:3f:40:bd:50:93:d3:9b:6c:60:f6:da:bc:07:62:01:00:89:76:c9
+# SHA256 Fingerprint: a4:5e:de:3b:bb:f0:9c:8a:e1:5c:72:ef:c0:72:68:d6:93:a2:1c:99:6f:d5:1e:67:ca:07:94:60:fd:6d:88:73
+-----BEGIN CERTIFICATE-----
+MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJC
+TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0
+aWZpY2F0aW9uIEF1dGhvcml0eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0
+aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAzMTkxODMzMzNaFw0yMTAzMTcxODMz
+MzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUw
+IwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVR
+dW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Yp
+li4kVEAkOPcahdxYTMukJ0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2D
+rOpm2RgbaIr1VxqYuvXtdj182d6UajtLF8HVj71lODqV0D1VNk7feVcxKh7YWWVJ
+WCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeLYzcS19Dsw3sgQUSj7cug
+F+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWenAScOospU
+xbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCC
+Ak4wPQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVv
+dmFkaXNvZmZzaG9yZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREw
+ggENMIIBCQYJKwYBBAG+WAABMIH7MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNl
+IG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBh
+c3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFy
+ZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh
+Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYI
+KwYBBQUHAgEWFmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3T
+KbkGGew5Oanwl4Rqy+/fMIGuBgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rq
+y+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1p
+dGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYD
+VQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6tlCL
+MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSk
+fnIYj9lofFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf8
+7C9TqnN7Az10buYWnuulLsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1R
+cHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2xgI4JVrmcGmD+XcHXetwReNDWXcG31a0y
+mQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi5upZIof4l/UO/erMkqQW
+xFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi5nrQNiOK
+SnQ2+Q==
+-----END CERTIFICATE-----
+
+# Issuer: CN=QuoVadis Root CA 2 O=QuoVadis Limited
+# Subject: CN=QuoVadis Root CA 2 O=QuoVadis Limited
+# Label: "QuoVadis Root CA 2"
+# Serial: 1289
+# MD5 Fingerprint: 5e:39:7b:dd:f8:ba:ec:82:e9:ac:62:ba:0c:54:00:2b
+# SHA1 Fingerprint: ca:3a:fb:cf:12:40:36:4b:44:b2:16:20:88:80:48:39:19:93:7c:f7
+# SHA256 Fingerprint: 85:a0:dd:7d:d7:20:ad:b7:ff:05:f8:3d:54:2b:20:9d:c7:ff:45:28:f7:d6:77:b1:83:89:fe:a5:e5:c4:9e:86
+-----BEGIN CERTIFICATE-----
+MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x
+GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv
+b3QgQ0EgMjAeFw0wNjExMjQxODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNV
+BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W
+YWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCa
+GMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6XJxg
+Fyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55J
+WpzmM+Yklvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bB
+rrcCaoF6qUWD4gXmuVbBlDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp
++ARz8un+XJiM9XOva7R+zdRcAitMOeGylZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1
+ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt66/3FsvbzSUr5R/7mp/i
+Ucw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1JdxnwQ5hYIiz
+PtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og
+/zOhD7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UH
+oycR7hYQe7xFSkyyBNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuI
+yV77zGHcizN300QyNQliBJIWENieJ0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1Ud
+EwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBQahGK8SEwzJQTU7tD2
+A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGUa6FJpEcwRTEL
+MAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT
+ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2f
+BluornFdLwUvZ+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzn
+g/iN/Ae42l9NLmeyhP3ZRPx3UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2Bl
+fF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodmVjB3pjd4M1IQWK4/YY7yarHvGH5K
+WWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK+JDSV6IZUaUtl0Ha
+B0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrWIozc
+hLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPR
+TUIZ3Ph1WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWD
+mbA4CD/pXvk1B+TJYm5Xf6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0Z
+ohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y
+4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8VCLAAVBpQ570su9t+Oza
+8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u
+-----END CERTIFICATE-----
+
+# Issuer: CN=QuoVadis Root CA 3 O=QuoVadis Limited
+# Subject: CN=QuoVadis Root CA 3 O=QuoVadis Limited
+# Label: "QuoVadis Root CA 3"
+# Serial: 1478
+# MD5 Fingerprint: 31:85:3c:62:94:97:63:b9:aa:fd:89:4e:af:6f:e0:cf
+# SHA1 Fingerprint: 1f:49:14:f7:d8:74:95:1d:dd:ae:02:c0:be:fd:3a:2d:82:75:51:85
+# SHA256 Fingerprint: 18:f1:fc:7f:20:5d:f8:ad:dd:eb:7f:e0:07:dd:57:e3:af:37:5a:9c:4d:8d:73:54:6b:f4:f1:fe:d1:e1:8d:35
+-----BEGIN CERTIFICATE-----
+MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x
+GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv
+b3QgQ0EgMzAeFw0wNjExMjQxOTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNV
+BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W
+YWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDM
+V0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNggDhoB
+4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUr
+H556VOijKTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd
+8lyyBTNvijbO0BNO/79KDDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9Cabwv
+vWhDFlaJKjdhkf2mrk7AyxRllDdLkgbvBNDInIjbC3uBr7E9KsRlOni27tyAsdLT
+mZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwpp5ijJUMv7/FfJuGITfhe
+btfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8nT8KKdjc
+T5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDt
+WAEXMJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZ
+c6tsgLjoC2SToJyMGf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A
+4iLItLRkT9a6fUg+qGkM17uGcclzuD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYD
+VR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHTBgkrBgEEAb5YAAMwgcUwgZMG
+CCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmljYXRlIGNvbnN0
+aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0
+aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVu
+dC4wLQYIKwYBBQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2Nw
+czALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4G
+A1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4ywLQoUmkRzBFMQswCQYDVQQGEwJC
+TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UEAxMSUXVvVmFkaXMg
+Um9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZVqyM0
+7ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSem
+d1o417+shvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd
++LJ2w/w4E6oM3kJpK27zPOuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B
+4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadN
+t54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp8kokUvd0/bpO5qgdAm6x
+DYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBCbjPsMZ57
+k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6s
+zHXug/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0j
+Wy10QJLZYxkNc91pvGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeT
+mJlglFwjz1onl14LBQaTNx47aTbrqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK
+4SVhM7JZG+Ju1zdXtg2pEto=
+-----END CERTIFICATE-----
+
+# Issuer: O=SECOM Trust.net OU=Security Communication RootCA1
+# Subject: O=SECOM Trust.net OU=Security Communication RootCA1
+# Label: "Security Communication Root CA"
+# Serial: 0
+# MD5 Fingerprint: f1:bc:63:6a:54:e0:b5:27:f5:cd:e7:1a:e3:4d:6e:4a
+# SHA1 Fingerprint: 36:b1:2b:49:f9:81:9e:d7:4c:9e:bc:38:0f:c6:56:8f:5d:ac:b2:f7
+# SHA256 Fingerprint: e7:5e:72:ed:9f:56:0e:ec:6e:b4:80:00:73:a4:3f:c3:ad:19:19:5a:39:22:82:01:78:95:97:4a:99:02:6b:6c
+-----BEGIN CERTIFICATE-----
+MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEY
+MBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21t
+dW5pY2F0aW9uIFJvb3RDQTEwHhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5
+WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYD
+VQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEwggEiMA0GCSqGSIb3
+DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw8yl8
+9f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJ
+DKaVv0uMDPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9
+Ms+k2Y7CI9eNqPPYJayX5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/N
+QV3Is00qVUarH9oe4kA92819uZKAnDfdDJZkndwi92SL32HeFZRSFaB9UslLqCHJ
+xrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2JChzAgMBAAGjPzA9MB0G
+A1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYwDwYDVR0T
+AQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vG
+kl3g0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfr
+Uj94nK9NrvjVT8+amCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5
+Bw+SUEmK3TGXX8npN6o7WWWXlDLJs58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJU
+JRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ6rBK+1YWc26sTfcioU+tHXot
+RSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAiFL39vmwLAw==
+-----END CERTIFICATE-----
+
+# Issuer: CN=Sonera Class2 CA O=Sonera
+# Subject: CN=Sonera Class2 CA O=Sonera
+# Label: "Sonera Class 2 Root CA"
+# Serial: 29
+# MD5 Fingerprint: a3:ec:75:0f:2e:88:df:fa:48:01:4e:0b:5c:48:6f:fb
+# SHA1 Fingerprint: 37:f7:6d:e6:07:7c:90:c5:b1:3e:93:1a:b7:41:10:b4:f2:e4:9a:27
+# SHA256 Fingerprint: 79:08:b4:03:14:c1:38:10:0b:51:8d:07:35:80:7f:fb:fc:f8:51:8a:00:95:33:71:05:ba:38:6b:15:3d:d9:27
+-----BEGIN CERTIFICATE-----
+MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEP
+MA0GA1UEChMGU29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAx
+MDQwNjA3Mjk0MFoXDTIxMDQwNjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNV
+BAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJhIENsYXNzMiBDQTCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3/Ei9vX+ALTU74W+o
+Z6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybTdXnt
+5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s
+3TmVToMGf+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2Ej
+vOr7nQKV0ba5cTppCD8PtOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu
+8nYybieDwnPz3BjotJPqdURrBGAgcVeHnfO+oJAjPYok4doh28MCAwEAAaMzMDEw
+DwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITTXjwwCwYDVR0PBAQDAgEG
+MA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt0jSv9zil
+zqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/
+3DEIcbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvD
+FNr450kkkdAdavphOe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6
+Tk6ezAyNlNzZRZxe7EJQY670XcSxEtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2
+ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLHllpwrN9M
+-----END CERTIFICATE-----
+
+# Issuer: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com
+# Subject: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com
+# Label: "XRamp Global CA Root"
+# Serial: 107108908803651509692980124233745014957
+# MD5 Fingerprint: a1:0b:44:b3:ca:10:d8:00:6e:9d:0f:d8:0f:92:0a:d1
+# SHA1 Fingerprint: b8:01:86:d1:eb:9c:86:a5:41:04:cf:30:54:f3:4c:52:b7:e5:58:c6
+# SHA256 Fingerprint: ce:cd:dc:90:50:99:d8:da:df:c5:b1:d2:09:b7:37:cb:e2:c1:8c:fb:2c:10:c0:ff:0b:cf:0d:32:86:fc:1a:a2
+-----BEGIN CERTIFICATE-----
+MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB
+gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk
+MCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY
+UmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx
+NDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3
+dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy
+dmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB
+dXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6
+38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP
+KZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q
+DxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4
+qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa
+JSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi
+PvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P
+BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs
+jVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0
+eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD
+ggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR
+vbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt
+qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa
+IR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy
+i6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ
+O+7ETPTsJ3xCwnR8gooJybQDJbw=
+-----END CERTIFICATE-----
+
+# Issuer: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority
+# Subject: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority
+# Label: "Go Daddy Class 2 CA"
+# Serial: 0
+# MD5 Fingerprint: 91:de:06:25:ab:da:fd:32:17:0c:bb:25:17:2a:84:67
+# SHA1 Fingerprint: 27:96:ba:e6:3f:18:01:e2:77:26:1b:a0:d7:77:70:02:8f:20:ee:e4
+# SHA256 Fingerprint: c3:84:6b:f2:4b:9e:93:ca:64:27:4c:0e:c6:7c:1e:cc:5e:02:4f:fc:ac:d2:d7:40:19:35:0e:81:fe:54:6a:e4
+-----BEGIN CERTIFICATE-----
+MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh
+MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE
+YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3
+MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo
+ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg
+MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN
+ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA
+PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w
+wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi
+EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY
+avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+
+YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE
+sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h
+/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5
+IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj
+YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
+ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy
+OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P
+TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ
+HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER
+dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf
+ReYNnyicsbkqWletNw+vHX/bvZ8=
+-----END CERTIFICATE-----
+
+# Issuer: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority
+# Subject: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority
+# Label: "Starfield Class 2 CA"
+# Serial: 0
+# MD5 Fingerprint: 32:4a:4b:bb:c8:63:69:9b:be:74:9a:c6:dd:1d:46:24
+# SHA1 Fingerprint: ad:7e:1c:28:b0:64:ef:8f:60:03:40:20:14:c3:d0:e3:37:0e:b5:8a
+# SHA256 Fingerprint: 14:65:fa:20:53:97:b8:76:fa:a6:f0:a9:95:8e:55:90:e4:0f:cc:7f:aa:4f:b7:c2:c8:67:75:21:fb:5f:b6:58
+-----BEGIN CERTIFICATE-----
+MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl
+MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp
+U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw
+NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE
+ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp
+ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3
+DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf
+8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN
++lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0
+X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa
+K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA
+1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G
+A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR
+zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0
+YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD
+bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w
+DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3
+L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D
+eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl
+xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp
+VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY
+WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q=
+-----END CERTIFICATE-----
+
+# Issuer: O=Government Root Certification Authority
+# Subject: O=Government Root Certification Authority
+# Label: "Taiwan GRCA"
+# Serial: 42023070807708724159991140556527066870
+# MD5 Fingerprint: 37:85:44:53:32:45:1f:20:f0:f3:95:e1:25:c4:43:4e
+# SHA1 Fingerprint: f4:8b:11:bf:de:ab:be:94:54:20:71:e6:41:de:6b:be:88:2b:40:b9
+# SHA256 Fingerprint: 76:00:29:5e:ef:e8:5b:9e:1f:d6:24:db:76:06:2a:aa:ae:59:81:8a:54:d2:77:4c:d4:c0:b2:c0:11:31:e1:b3
+-----BEGIN CERTIFICATE-----
+MIIFcjCCA1qgAwIBAgIQH51ZWtcvwgZEpYAIaeNe9jANBgkqhkiG9w0BAQUFADA/
+MQswCQYDVQQGEwJUVzEwMC4GA1UECgwnR292ZXJubWVudCBSb290IENlcnRpZmlj
+YXRpb24gQXV0aG9yaXR5MB4XDTAyMTIwNTEzMjMzM1oXDTMyMTIwNTEzMjMzM1ow
+PzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dvdmVybm1lbnQgUm9vdCBDZXJ0aWZp
+Y2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
+AJoluOzMonWoe/fOW1mKydGGEghU7Jzy50b2iPN86aXfTEc2pBsBHH8eV4qNw8XR
+IePaJD9IK/ufLqGU5ywck9G/GwGHU5nOp/UKIXZ3/6m3xnOUT0b3EEk3+qhZSV1q
+gQdW8or5BtD3cCJNtLdBuTK4sfCxw5w/cP1T3YGq2GN49thTbqGsaoQkclSGxtKy
+yhwOeYHWtXBiCAEuTk8O1RGvqa/lmr/czIdtJuTJV6L7lvnM4T9TjGxMfptTCAts
+F/tnyMKtsc2AtJfcdgEWFelq16TheEfOhtX7MfP6Mb40qij7cEwdScevLJ1tZqa2
+jWR+tSBqnTuBto9AAGdLiYa4zGX+FVPpBMHWXx1E1wovJ5pGfaENda1UhhXcSTvx
+ls4Pm6Dso3pdvtUqdULle96ltqqvKKyskKw4t9VoNSZ63Pc78/1Fm9G7Q3hub/FC
+VGqY8A2tl+lSXunVanLeavcbYBT0peS2cWeqH+riTcFCQP5nRhc4L0c/cZyu5SHK
+YS1tB6iEfC3uUSXxY5Ce/eFXiGvviiNtsea9P63RPZYLhY3Naye7twWb7LuRqQoH
+EgKXTiCQ8P8NHuJBO9NAOueNXdpm5AKwB1KYXA6OM5zCppX7VRluTI6uSw+9wThN
+Xo+EHWbNxWCWtFJaBYmOlXqYwZE8lSOyDvR5tMl8wUohAgMBAAGjajBoMB0GA1Ud
+DgQWBBTMzO/MKWCkO7GStjz6MmKPrCUVOzAMBgNVHRMEBTADAQH/MDkGBGcqBwAE
+MTAvMC0CAQAwCQYFKw4DAhoFADAHBgVnKgMAAAQUA5vwIhP/lSg209yewDL7MTqK
+UWUwDQYJKoZIhvcNAQEFBQADggIBAECASvomyc5eMN1PhnR2WPWus4MzeKR6dBcZ
+TulStbngCnRiqmjKeKBMmo4sIy7VahIkv9Ro04rQ2JyftB8M3jh+Vzj8jeJPXgyf
+qzvS/3WXy6TjZwj/5cAWtUgBfen5Cv8b5Wppv3ghqMKnI6mGq3ZW6A4M9hPdKmaK
+ZEk9GhiHkASfQlK3T8v+R0F2Ne//AHY2RTKbxkaFXeIksB7jSJaYV0eUVXoPQbFE
+JPPB/hprv4j9wabak2BegUqZIJxIZhm1AHlUD7gsL0u8qV1bYH+Mh6XgUmMqvtg7
+hUAV/h62ZT/FS9p+tXo1KaMuephgIqP0fSdOLeq0dDzpD6QzDxARvBMB1uUO07+1
+EqLhRSPAzAhuYbeJq4PjJB7mXQfnHyA+z2fI56wwbSdLaG5LKlwCCDTb+HbkZ6Mm
+nD+iMsJKxYEYMRBWqoTvLQr/uB930r+lWKBi5NdLkXWNiYCYfm3LU05er/ayl4WX
+udpVBrkk7tfGOB5jGxI7leFYrPLfhNVfmS8NVVvmONsuP3LpSIXLuykTjx44Vbnz
+ssQwmSNOXfJIoRIM3BKQCZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDe
+LMDDav7v3Aun+kbfYNucpllQdSNpc5Oy+fwC00fmcc4QAu4njIT/rEUNE1yDMuAl
+pYYsfPQS
+-----END CERTIFICATE-----
+
+# Issuer: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com
+# Subject: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com
+# Label: "DigiCert Assured ID Root CA"
+# Serial: 17154717934120587862167794914071425081
+# MD5 Fingerprint: 87:ce:0b:7b:2a:0e:49:00:e1:58:71:9b:37:a8:93:72
+# SHA1 Fingerprint: 05:63:b8:63:0d:62:d7:5a:bb:c8:ab:1e:4b:df:b5:a8:99:b2:4d:43
+# SHA256 Fingerprint: 3e:90:99:b5:01:5e:8f:48:6c:00:bc:ea:9d:11:1e:e7:21:fa:ba:35:5a:89:bc:f1:df:69:56:1e:3d:c6:32:5c
+-----BEGIN CERTIFICATE-----
+MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv
+b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG
+EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl
+cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi
+MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c
+JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP
+mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+
+wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4
+VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/
+AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB
+AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
+BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun
+pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC
+dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf
+fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm
+NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx
+H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe
++o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g==
+-----END CERTIFICATE-----
+
+# Issuer: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com
+# Subject: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com
+# Label: "DigiCert Global Root CA"
+# Serial: 10944719598952040374951832963794454346
+# MD5 Fingerprint: 79:e4:a9:84:0d:7d:3a:96:d7:c0:4f:e2:43:4c:89:2e
+# SHA1 Fingerprint: a8:98:5d:3a:65:e5:e5:c4:b2:d7:d6:6d:40:c6:dd:2f:b1:9c:54:36
+# SHA256 Fingerprint: 43:48:a0:e9:44:4c:78:cb:26:5e:05:8d:5e:89:44:b4:d8:4f:96:62:bd:26:db:25:7f:89:34:a4:43:c7:01:61
+-----BEGIN CERTIFICATE-----
+MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
+QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
+MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
+b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
+CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
+nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
+43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
+T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
+gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
+BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
+TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
+DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
+hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
+06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
+PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
+YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
+CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
+-----END CERTIFICATE-----
+
+# Issuer: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com
+# Subject: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com
+# Label: "DigiCert High Assurance EV Root CA"
+# Serial: 3553400076410547919724730734378100087
+# MD5 Fingerprint: d4:74:de:57:5c:39:b2:d3:9c:85:83:c5:c0:65:49:8a
+# SHA1 Fingerprint: 5f:b7:ee:06:33:e2:59:db:ad:0c:4c:9a:e6:d3:8f:1a:61:c7:dc:25
+# SHA256 Fingerprint: 74:31:e5:f4:c3:c1:ce:46:90:77:4f:0b:61:e0:54:40:88:3b:a9:a0:1e:d0:0b:a6:ab:d7:80:6e:d3:b1:18:cf
+-----BEGIN CERTIFICATE-----
+MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
+ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL
+MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
+LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
+RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm
++9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW
+PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM
+xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB
+Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3
+hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg
+EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF
+MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA
+FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec
+nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z
+eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF
+hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
+Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
+vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
++OkuE6N36B9K
+-----END CERTIFICATE-----
+
+# Issuer: CN=Class 2 Primary CA O=Certplus
+# Subject: CN=Class 2 Primary CA O=Certplus
+# Label: "Certplus Class 2 Primary CA"
+# Serial: 177770208045934040241468760488327595043
+# MD5 Fingerprint: 88:2c:8c:52:b8:a2:3c:f3:f7:bb:03:ea:ae:ac:42:0b
+# SHA1 Fingerprint: 74:20:74:41:72:9c:dd:92:ec:79:31:d8:23:10:8d:c2:81:92:e2:bb
+# SHA256 Fingerprint: 0f:99:3c:8a:ef:97:ba:af:56:87:14:0e:d5:9a:d1:82:1b:b4:af:ac:f0:aa:9a:58:b5:d5:7a:33:8a:3a:fb:cb
+-----BEGIN CERTIFICATE-----
+MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAw
+PTELMAkGA1UEBhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFz
+cyAyIFByaW1hcnkgQ0EwHhcNOTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9
+MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2VydHBsdXMxGzAZBgNVBAMTEkNsYXNz
+IDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANxQ
+ltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR5aiR
+VhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyL
+kcAbmXuZVg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCd
+EgETjdyAYveVqUSISnFOYFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yas
+H7WLO7dDWWuwJKZtkIvEcupdM5i3y95ee++U8Rs+yskhwcWYAqqi9lt3m/V+llU0
+HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRMECDAGAQH/AgEKMAsGA1Ud
+DwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJYIZIAYb4
+QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMu
+Y29tL0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/
+AN9WM2K191EBkOvDP9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8
+yfFC82x/xXp8HVGIutIKPidd3i1RTtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMR
+FcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+7UCmnYR0ObncHoUW2ikbhiMA
+ybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW//1IMwrh3KWB
+kJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7
+l7+ijrRU
+-----END CERTIFICATE-----
+
+# Issuer: CN=DST Root CA X3 O=Digital Signature Trust Co.
+# Subject: CN=DST Root CA X3 O=Digital Signature Trust Co.
+# Label: "DST Root CA X3"
+# Serial: 91299735575339953335919266965803778155
+# MD5 Fingerprint: 41:03:52:dc:0f:f7:50:1b:16:f0:02:8e:ba:6f:45:c5
+# SHA1 Fingerprint: da:c9:02:4f:54:d8:f6:df:94:93:5f:b1:73:26:38:ca:6a:d7:7c:13
+# SHA256 Fingerprint: 06:87:26:03:31:a7:24:03:d9:09:f1:05:e6:9b:cf:0d:32:e1:bd:24:93:ff:c6:d9:20:6d:11:bc:d6:77:07:39
+-----BEGIN CERTIFICATE-----
+MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/
+MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
+DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow
+PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD
+Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O
+rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq
+OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b
+xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw
+7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD
+aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
+HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG
+SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69
+ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr
+AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz
+R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5
+JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo
+Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
+-----END CERTIFICATE-----
+
+# Issuer: CN=SwissSign Gold CA - G2 O=SwissSign AG
+# Subject: CN=SwissSign Gold CA - G2 O=SwissSign AG
+# Label: "SwissSign Gold CA - G2"
+# Serial: 13492815561806991280
+# MD5 Fingerprint: 24:77:d9:a8:91:d1:3b:fa:88:2d:c2:ff:f8:cd:33:93
+# SHA1 Fingerprint: d8:c5:38:8a:b7:30:1b:1b:6e:d4:7a:e6:45:25:3a:6f:9f:1a:27:61
+# SHA256 Fingerprint: 62:dd:0b:e9:b9:f5:0a:16:3e:a0:f8:e7:5c:05:3b:1e:ca:57:ea:55:c8:68:8f:64:7c:68:81:f2:c8:35:7b:95
+-----BEGIN CERTIFICATE-----
+MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
+BAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2ln
+biBHb2xkIENBIC0gRzIwHhcNMDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBF
+MQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMR8wHQYDVQQDExZT
+d2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
+CgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUqt2/8
+76LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+
+bbqBHH5CjCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c
+6bM8K8vzARO/Ws/BtQpgvd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqE
+emA8atufK+ze3gE/bk3lUIbLtK/tREDFylqM2tIrfKjuvqblCqoOpd8FUrdVxyJd
+MmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvRAiTysybUa9oEVeXBCsdt
+MDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuendjIj3o02y
+MszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69y
+FGkOpeUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPi
+aG59je883WX0XaxR7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxM
+gI93e2CaHt+28kgeDrpOVG2Y4OGiGqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCB
+qTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUWyV7
+lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64OfPAeGZe6Drn
+8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov
+L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe6
+45R88a7A3hfm5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczO
+UYrHUDFu4Up+GC9pWbY9ZIEr44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5
+O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOfMke6UiI0HTJ6CVanfCU2qT1L2sCC
+bwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6mGu6uLftIdxf+u+yv
+GPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxpmo/a
+77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCC
+hdiDyyJkvC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid3
+92qgQmwLOM7XdVAyksLfKzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEpp
+Ld6leNcG2mqeSz53OiATIgHQv2ieY2BrNU0LbbqhPcCT4H8js1WtciVORvnSFu+w
+ZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6LqjviOvrv1vA+ACOzB2+htt
+Qc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ
+-----END CERTIFICATE-----
+
+# Issuer: CN=SwissSign Silver CA - G2 O=SwissSign AG
+# Subject: CN=SwissSign Silver CA - G2 O=SwissSign AG
+# Label: "SwissSign Silver CA - G2"
+# Serial: 5700383053117599563
+# MD5 Fingerprint: e0:06:a1:c9:7d:cf:c9:fc:0d:c0:56:75:96:d8:62:13
+# SHA1 Fingerprint: 9b:aa:e5:9f:56:ee:21:cb:43:5a:be:25:93:df:a7:f0:40:d1:1d:cb
+# SHA256 Fingerprint: be:6c:4d:a2:bb:b9:ba:59:b6:f3:93:97:68:37:42:46:c3:c0:05:99:3f:a9:8f:02:0d:1d:ed:be:d4:8a:81:d5
+-----BEGIN CERTIFICATE-----
+MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UE
+BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWdu
+IFNpbHZlciBDQSAtIEcyMB4XDTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0Nlow
+RzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMY
+U3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A
+MIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644N0Mv
+Fz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7br
+YT7QbNHm+/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieF
+nbAVlDLaYQ1HTWBCrpJH6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH
+6ATK72oxh9TAtvmUcXtnZLi2kUpCe2UuMGoM9ZDulebyzYLs2aFK7PayS+VFheZt
+eJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5hqAaEuSh6XzjZG6k4sIN/
+c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5FZGkECwJ
+MoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRH
+HTBsROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTf
+jNFusB3hB48IHpmccelM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb6
+5i/4z3GcRm25xBWNOHkDRUjvxF3XCO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOB
+rDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU
+F6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRBtjpbO8tFnb0c
+wpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0
+cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIB
+AHPGgeAn0i0P4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShp
+WJHckRE1qTodvBqlYJ7YH39FkWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9
+xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L3XWgwF15kIwb4FDm3jH+mHtwX6WQ
+2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx/uNncqCxv1yL5PqZ
+IseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFaDGi8
+aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2X
+em1ZqSqPe97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQR
+dAtq/gsD/KNVV4n+SsuuWxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/
+OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJDIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+
+hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ubDgEj8Z+7fNzcbBGXJbLy
+tGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u
+-----END CERTIFICATE-----
+
+# Issuer: CN=GeoTrust Primary Certification Authority O=GeoTrust Inc.
+# Subject: CN=GeoTrust Primary Certification Authority O=GeoTrust Inc.
+# Label: "GeoTrust Primary Certification Authority"
+# Serial: 32798226551256963324313806436981982369
+# MD5 Fingerprint: 02:26:c3:01:5e:08:30:37:43:a9:d0:7d:cf:37:e6:bf
+# SHA1 Fingerprint: 32:3c:11:8e:1b:f7:b8:b6:52:54:e2:e2:10:0d:d6:02:90:37:f0:96
+# SHA256 Fingerprint: 37:d5:10:06:c5:12:ea:ab:62:64:21:f1:ec:8c:92:01:3f:c5:f8:2a:e9:8e:e5:33:eb:46:19:b8:de:b4:d0:6c
+-----BEGIN CERTIFICATE-----
+MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBY
+MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMo
+R2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEx
+MjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgxCzAJBgNVBAYTAlVTMRYwFAYDVQQK
+Ew1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQcmltYXJ5IENlcnRp
+ZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
+AQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9
+AWbK7hWNb6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjA
+ZIVcFU2Ix7e64HXprQU9nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE0
+7e9GceBrAqg1cmuXm2bgyxx5X9gaBGgeRwLmnWDiNpcB3841kt++Z8dtd1k7j53W
+kBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGttm/81w7a4DSwDRp35+MI
+mO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G
+A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJ
+KoZIhvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ1
+6CePbJC/kRYkRj5KTs4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl
+4b7UVXGYNTq+k+qurUKykG/g/CFNNWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6K
+oKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHaFloxt/m0cYASSJlyc1pZU8Fj
+UjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG1riR/aYNKxoU
+AT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk=
+-----END CERTIFICATE-----
+
+# Issuer: CN=thawte Primary Root CA O=thawte, Inc. OU=Certification Services Division/(c) 2006 thawte, Inc. - For authorized use only
+# Subject: CN=thawte Primary Root CA O=thawte, Inc. OU=Certification Services Division/(c) 2006 thawte, Inc. - For authorized use only
+# Label: "thawte Primary Root CA"
+# Serial: 69529181992039203566298953787712940909
+# MD5 Fingerprint: 8c:ca:dc:0b:22:ce:f5:be:72:ac:41:1a:11:a8:d8:12
+# SHA1 Fingerprint: 91:c6:d6:ee:3e:8a:c8:63:84:e5:48:c2:99:29:5c:75:6c:81:7b:81
+# SHA256 Fingerprint: 8d:72:2f:81:a9:c1:13:c0:79:1d:f1:36:a2:96:6d:b2:6c:95:0a:97:1d:b4:6b:41:99:f4:ea:54:b7:8b:fb:9f
+-----BEGIN CERTIFICATE-----
+MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCB
+qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
+Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
+MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV
+BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3MDAwMDAwWhcNMzYw
+NzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5j
+LjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYG
+A1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
+IG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqG
+SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsoPD7gFnUnMekz52hWXMJEEUMDSxuaPFs
+W0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ1CRfBsDMRJSUjQJib+ta
+3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGcq/gcfomk
+6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6
+Sk/KaAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94J
+NqR32HuHUETVPm4pafs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBA
+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XP
+r87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUFAAOCAQEAeRHAS7ORtvzw6WfU
+DW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeEuzLlQRHAd9mz
+YJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX
+xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2
+/qxAeeWsEG89jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/
+LHbTY5xZ3Y+m4Q6gLkH3LpVHz7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7
+jVaMaA==
+-----END CERTIFICATE-----
+
+# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G5 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2006 VeriSign, Inc. - For authorized use only
+# Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G5 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2006 VeriSign, Inc. - For authorized use only
+# Label: "VeriSign Class 3 Public Primary Certification Authority - G5"
+# Serial: 33037644167568058970164719475676101450
+# MD5 Fingerprint: cb:17:e4:31:67:3e:e2:09:fe:45:57:93:f3:0a:fa:1c
+# SHA1 Fingerprint: 4e:b6:d5:78:49:9b:1c:cf:5f:58:1e:ad:56:be:3d:9b:67:44:a5:e5
+# SHA256 Fingerprint: 9a:cf:ab:7e:43:c8:d8:80:d0:6b:26:2a:94:de:ee:e4:b4:65:99:89:c3:d0:ca:f1:9b:af:64:05:e4:1a:b7:df
+-----BEGIN CERTIFICATE-----
+MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB
+yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
+ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
+U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
+ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
+aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL
+MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
+ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln
+biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp
+U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y
+aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1
+nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex
+t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz
+SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG
+BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+
+rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/
+NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E
+BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH
+BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy
+aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv
+MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE
+p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y
+5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK
+WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ
+4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N
+hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq
+-----END CERTIFICATE-----
+
+# Issuer: CN=SecureTrust CA O=SecureTrust Corporation
+# Subject: CN=SecureTrust CA O=SecureTrust Corporation
+# Label: "SecureTrust CA"
+# Serial: 17199774589125277788362757014266862032
+# MD5 Fingerprint: dc:32:c3:a7:6d:25:57:c7:68:09:9d:ea:2d:a9:a2:d1
+# SHA1 Fingerprint: 87:82:c6:c3:04:35:3b:cf:d2:96:92:d2:59:3e:7d:44:d9:34:ff:11
+# SHA256 Fingerprint: f1:c1:b5:0a:e5:a2:0d:d8:03:0e:c9:f6:bc:24:82:3d:d3:67:b5:25:57:59:b4:e7:1b:61:fc:e9:f7:37:5d:73
+-----BEGIN CERTIFICATE-----
+MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI
+MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x
+FzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz
+MTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv
+cnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN
+AQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz
+Zum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO
+0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao
+wW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj
+7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS
+8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT
+BgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB
+/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg
+JYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC
+NxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3
+6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/
+3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm
+D5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS
+CPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR
+3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE=
+-----END CERTIFICATE-----
+
+# Issuer: CN=Secure Global CA O=SecureTrust Corporation
+# Subject: CN=Secure Global CA O=SecureTrust Corporation
+# Label: "Secure Global CA"
+# Serial: 9751836167731051554232119481456978597
+# MD5 Fingerprint: cf:f4:27:0d:d4:ed:dc:65:16:49:6d:3d:da:bf:6e:de
+# SHA1 Fingerprint: 3a:44:73:5a:e5:81:90:1f:24:86:61:46:1e:3b:9c:c4:5f:f5:3a:1b
+# SHA256 Fingerprint: 42:00:f5:04:3a:c8:59:0e:bb:52:7d:20:9e:d1:50:30:29:fb:cb:d4:1c:a1:b5:06:ec:27:f1:5a:de:7d:ac:69
+-----BEGIN CERTIFICATE-----
+MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBK
+MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x
+GTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkx
+MjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3Qg
+Q29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwggEiMA0GCSqG
+SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jxYDiJ
+iQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa
+/FHtaMbQbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJ
+jnIFHovdRIWCQtBJwB1g8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnI
+HmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYVHDGA76oYa8J719rO+TMg1fW9ajMtgQT7
+sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi0XPnj3pDAgMBAAGjgZ0w
+gZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF
+MAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCsw
+KaAnoCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsG
+AQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0L
+URYD7xh8yOOvaliTFGCRsoTciE6+OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXO
+H0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cnCDpOGR86p1hcF895P4vkp9Mm
+I50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/53CYNv6ZHdAbY
+iNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc
+f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW
+-----END CERTIFICATE-----
+
+# Issuer: CN=COMODO Certification Authority O=COMODO CA Limited
+# Subject: CN=COMODO Certification Authority O=COMODO CA Limited
+# Label: "COMODO Certification Authority"
+# Serial: 104350513648249232941998508985834464573
+# MD5 Fingerprint: 5c:48:dc:f7:42:72:ec:56:94:6d:1c:cc:71:35:80:75
+# SHA1 Fingerprint: 66:31:bf:9e:f7:4f:9e:b6:c9:d5:a6:0c:ba:6a:be:d1:f7:bd:ef:7b
+# SHA256 Fingerprint: 0c:2c:d6:3d:f7:80:6f:a3:99:ed:e8:09:11:6b:57:5b:f8:79:89:f0:65:18:f9:80:8c:86:05:03:17:8b:af:66
+-----BEGIN CERTIFICATE-----
+MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB
+gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
+A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV
+BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw
+MDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl
+YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P
+RE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0
+aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3
+UcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI
+2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8
+Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp
++2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+
+DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O
+nKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW
+/zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g
+PKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u
+QXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY
+SdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv
+IC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/
+RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4
+zJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd
+BA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB
+ZQ==
+-----END CERTIFICATE-----
+
+# Issuer: CN=Network Solutions Certificate Authority O=Network Solutions L.L.C.
+# Subject: CN=Network Solutions Certificate Authority O=Network Solutions L.L.C.
+# Label: "Network Solutions Certificate Authority"
+# Serial: 116697915152937497490437556386812487904
+# MD5 Fingerprint: d3:f3:a6:16:c0:fa:6b:1d:59:b1:2d:96:4d:0e:11:2e
+# SHA1 Fingerprint: 74:f8:a3:c3:ef:e7:b3:90:06:4b:83:90:3c:21:64:60:20:e5:df:ce
+# SHA256 Fingerprint: 15:f0:ba:00:a3:ac:7a:f3:ac:88:4c:07:2b:10:11:a0:77:bd:77:c0:97:f4:01:64:b2:f8:59:8a:bd:83:86:0c
+-----BEGIN CERTIFICATE-----
+MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBi
+MQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu
+MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3Jp
+dHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMxMjM1OTU5WjBiMQswCQYDVQQGEwJV
+UzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydO
+ZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqG
+SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwz
+c7MEL7xxjOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPP
+OCwGJgl6cvf6UDL4wpPTaaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rl
+mGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXTcrA/vGp97Eh/jcOrqnErU2lBUzS1sLnF
+BgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc/Qzpf14Dl847ABSHJ3A4
+qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMBAAGjgZcw
+gZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIB
+BjAPBgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwu
+bmV0c29sc3NsLmNvbS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3Jp
+dHkuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc8
+6fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q4LqILPxFzBiwmZVRDuwduIj/
+h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/GGUsyfJj4akH
+/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv
+wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHN
+pGxlaKFJdlxDydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey
+-----END CERTIFICATE-----
+
+# Issuer: CN=COMODO ECC Certification Authority O=COMODO CA Limited
+# Subject: CN=COMODO ECC Certification Authority O=COMODO CA Limited
+# Label: "COMODO ECC Certification Authority"
+# Serial: 41578283867086692638256921589707938090
+# MD5 Fingerprint: 7c:62:ff:74:9d:31:53:5e:68:4a:d5:78:aa:1e:bf:23
+# SHA1 Fingerprint: 9f:74:4e:9f:2b:4d:ba:ec:0f:31:2c:50:b6:56:3b:8e:2d:93:c3:11
+# SHA256 Fingerprint: 17:93:92:7a:06:14:54:97:89:ad:ce:2f:8f:34:f7:f0:b6:6d:0f:3a:e3:a3:b8:4d:21:ec:15:db:ba:4f:ad:c7
+-----BEGIN CERTIFICATE-----
+MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL
+MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE
+BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT
+IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw
+MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy
+ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N
+T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv
+biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR
+FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J
+cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW
+BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/
+BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm
+fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv
+GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY=
+-----END CERTIFICATE-----
+
+# Issuer: CN=OISTE WISeKey Global Root GA CA O=WISeKey OU=Copyright (c) 2005/OISTE Foundation Endorsed
+# Subject: CN=OISTE WISeKey Global Root GA CA O=WISeKey OU=Copyright (c) 2005/OISTE Foundation Endorsed
+# Label: "OISTE WISeKey Global Root GA CA"
+# Serial: 86718877871133159090080555911823548314
+# MD5 Fingerprint: bc:6c:51:33:a7:e9:d3:66:63:54:15:72:1b:21:92:93
+# SHA1 Fingerprint: 59:22:a1:e1:5a:ea:16:35:21:f8:98:39:6a:46:46:b0:44:1b:0f:a9
+# SHA256 Fingerprint: 41:c9:23:86:6a:b4:ca:d6:b7:ad:57:80:81:58:2e:02:07:97:a6:cb:df:4f:ff:78:ce:83:96:b3:89:37:d7:f5
+-----BEGIN CERTIFICATE-----
+MIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCB
+ijELMAkGA1UEBhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHly
+aWdodCAoYykgMjAwNTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNl
+ZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQSBDQTAeFw0w
+NTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYDVQQGEwJDSDEQMA4G
+A1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIwIAYD
+VQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBX
+SVNlS2V5IEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
+MIIBCgKCAQEAy0+zAJs9Nt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxR
+VVuuk+g3/ytr6dTqvirdqFEr12bDYVxgAsj1znJ7O7jyTmUIms2kahnBAbtzptf2
+w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbDd50kc3vkDIzh2TbhmYsF
+mQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ/yxViJGg
+4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t9
+4B3RLoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYw
+DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQw
+EAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOx
+SPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vImMMkQyh2I+3QZH4VFvbBsUfk2
+ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4+vg1YFkCExh8
+vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa
+hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZi
+Fj4A4xylNoEYokxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ
+/L7fCg0=
+-----END CERTIFICATE-----
+
+# Issuer: CN=Certigna O=Dhimyotis
+# Subject: CN=Certigna O=Dhimyotis
+# Label: "Certigna"
+# Serial: 18364802974209362175
+# MD5 Fingerprint: ab:57:a6:5b:7d:42:82:19:b5:d8:58:26:28:5e:fd:ff
+# SHA1 Fingerprint: b1:2e:13:63:45:86:a4:6f:1a:b2:60:68:37:58:2d:c4:ac:fd:94:97
+# SHA256 Fingerprint: e3:b6:a2:db:2e:d7:ce:48:84:2f:7a:c5:32:41:c7:b7:1d:54:14:4b:fb:40:c1:1f:3f:1d:0b:42:f5:ee:a1:2d
+-----BEGIN CERTIFICATE-----
+MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNV
+BAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4X
+DTA3MDYyOTE1MTMwNVoXDTI3MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQ
+BgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwIQ2VydGlnbmEwggEiMA0GCSqGSIb3
+DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7qXOEm7RFHYeGifBZ4
+QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyHGxny
+gQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbw
+zBfsV1/pogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q
+130yGLMLLGq/jj8UEYkgDncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2
+JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKfIrjxwo1p3Po6WAbfAgMBAAGjgbwwgbkw
+DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQtCRZvgHyUtVF9lo53BEw
+ZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJBgNVBAYT
+AkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzj
+AQ/JSP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG
+9w0BAQUFAAOCAQEAhQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8h
+bV6lUmPOEvjvKtpv6zf+EwLHyzs+ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFnc
+fca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1kluPBS1xp81HlDQwY9qcEQCYsuu
+HWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY1gkIl2PlwS6w
+t0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw
+WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg==
+-----END CERTIFICATE-----
+
+# Issuer: CN=Deutsche Telekom Root CA 2 O=Deutsche Telekom AG OU=T-TeleSec Trust Center
+# Subject: CN=Deutsche Telekom Root CA 2 O=Deutsche Telekom AG OU=T-TeleSec Trust Center
+# Label: "Deutsche Telekom Root CA 2"
+# Serial: 38
+# MD5 Fingerprint: 74:01:4a:91:b1:08:c4:58:ce:47:cd:f0:dd:11:53:08
+# SHA1 Fingerprint: 85:a4:08:c0:9c:19:3e:5d:51:58:7d:cd:d6:13:30:fd:8c:de:37:bf
+# SHA256 Fingerprint: b6:19:1a:50:d0:c3:97:7f:7d:a9:9b:cd:aa:c8:6a:22:7d:ae:b9:67:9e:c7:0b:a3:b0:c9:d9:22:71:c1:70:d3
+-----BEGIN CERTIFICATE-----
+MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEc
+MBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2Vj
+IFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENB
+IDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5MjM1OTAwWjBxMQswCQYDVQQGEwJE
+RTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxl
+U2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290
+IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEU
+ha88EOQ5bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhC
+QN/Po7qCWWqSG6wcmtoIKyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1Mjwr
+rFDa1sPeg5TKqAyZMg4ISFZbavva4VhYAUlfckE8FQYBjl2tqriTtM2e66foai1S
+NNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aKSe5TBY8ZTNXeWHmb0moc
+QqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTVjlsB9WoH
+txa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAP
+BgNVHRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOC
+AQEAlGRZrTlk5ynrE/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756Abrsp
+tJh6sTtU6zkXR34ajgv8HzFZMQSyzhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpa
+IzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8rZ7/gFnkm0W09juwzTkZmDLl
+6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4Gdyd1Lx+4ivn+
+xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU
+Cm26OWMohpLzGITY+9HPBVZkVw==
+-----END CERTIFICATE-----
+
+# Issuer: CN=Cybertrust Global Root O=Cybertrust, Inc
+# Subject: CN=Cybertrust Global Root O=Cybertrust, Inc
+# Label: "Cybertrust Global Root"
+# Serial: 4835703278459682877484360
+# MD5 Fingerprint: 72:e4:4a:87:e3:69:40:80:77:ea:bc:e3:f4:ff:f0:e1
+# SHA1 Fingerprint: 5f:43:e5:b1:bf:f8:78:8c:ac:1c:c7:ca:4a:9a:c6:22:2b:cc:34:c6
+# SHA256 Fingerprint: 96:0a:df:00:63:e9:63:56:75:0c:29:65:dd:0a:08:67:da:0b:9c:bd:6e:77:71:4a:ea:fb:23:49:ab:39:3d:a3
+-----BEGIN CERTIFICATE-----
+MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYG
+A1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2Jh
+bCBSb290MB4XDTA2MTIxNTA4MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UE
+ChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBS
+b290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+Mi8vRRQZhP/8NN5
+7CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW0ozS
+J8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2y
+HLtgwEZLAfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iP
+t3sMpTjr3kfb1V05/Iin89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNz
+FtApD0mpSPCzqrdsxacwOUBdrsTiXSZT8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAY
+XSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/
+MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2MDSgMqAw
+hi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3Js
+MB8GA1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUA
+A4IBAQBW7wojoFROlZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMj
+Wqd8BfP9IjsO0QbE2zZMcwSO5bAi5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUx
+XOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2hO0j9n0Hq0V+09+zv+mKts2o
+omcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+TX3EJIrduPuoc
+A06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW
+WL1WMRJOEcgh4LMRkWXbtKaIOM5V
+-----END CERTIFICATE-----
+
+# Issuer: O=Chunghwa Telecom Co., Ltd. OU=ePKI Root Certification Authority
+# Subject: O=Chunghwa Telecom Co., Ltd. OU=ePKI Root Certification Authority
+# Label: "ePKI Root Certification Authority"
+# Serial: 28956088682735189655030529057352760477
+# MD5 Fingerprint: 1b:2e:00:ca:26:06:90:3d:ad:fe:6f:15:68:d3:6b:b3
+# SHA1 Fingerprint: 67:65:0d:f1:7e:8e:7e:5b:82:40:a4:f4:56:4b:cf:e2:3d:69:c6:f0
+# SHA256 Fingerprint: c0:a6:f4:dc:63:a2:4b:fd:cf:54:ef:2a:6a:08:2a:0a:72:de:35:80:3e:2f:f5:ff:52:7a:e5:d8:72:06:df:d5
+-----BEGIN CERTIFICATE-----
+MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBe
+MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0
+ZC4xKjAoBgNVBAsMIWVQS0kgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe
+Fw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMxMjdaMF4xCzAJBgNVBAYTAlRXMSMw
+IQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEqMCgGA1UECwwhZVBL
+SSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEF
+AAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAH
+SyZbCUNsIZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAh
+ijHyl3SJCRImHJ7K2RKilTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3X
+DZoTM1PRYfl61dd4s5oz9wCGzh1NlDivqOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1
+TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX12ruOzjjK9SXDrkb5wdJ
+fzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0OWQqraffA
+sgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uU
+WH1+ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLS
+nT0IFaUQAS2zMnaolQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pH
+dmX2Os+PYhcZewoozRrSgx4hxyy/vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJip
+NiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXiZo1jDiVN1Rmy5nk3pyKdVDEC
+AwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/QkqiMAwGA1UdEwQF
+MAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH
+ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGB
+uvl2ICO1J2B01GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6Yl
+PwZpVnPDimZI+ymBV3QGypzqKOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkP
+JXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdVxrsStZf0X4OFunHB2WyBEXYKCrC/
+gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEPNXubrjlpC2JgQCA2
+j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+rGNm6
+5ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUB
+o2M3IUxExJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS
+/jQ6fbjpKdx2qcgw+BRxgMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2z
+Gp1iro2C6pSe3VkQw63d4k3jMdXH7OjysP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTE
+W9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmODBCEIZ43ygknQW/2xzQ+D
+hNQ+IIX3Sj0rnP0qCglN6oH4EZw=
+-----END CERTIFICATE-----
+
+# Issuer: O=certSIGN OU=certSIGN ROOT CA
+# Subject: O=certSIGN OU=certSIGN ROOT CA
+# Label: "certSIGN ROOT CA"
+# Serial: 35210227249154
+# MD5 Fingerprint: 18:98:c0:d6:e9:3a:fc:f9:b0:f5:0c:f7:4b:01:44:17
+# SHA1 Fingerprint: fa:b7:ee:36:97:26:62:fb:2d:b0:2a:f6:bf:03:fd:e8:7c:4b:2f:9b
+# SHA256 Fingerprint: ea:a9:62:c4:fa:4a:6b:af:eb:e4:15:19:6d:35:1c:cd:88:8d:4f:53:f3:fa:8a:e6:d7:c4:66:a9:4e:60:42:bb
+-----BEGIN CERTIFICATE-----
+MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYT
+AlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBD
+QTAeFw0wNjA3MDQxNzIwMDRaFw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJP
+MREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTCC
+ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7IJUqOtdu0KBuqV5Do
+0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHHrfAQ
+UySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5d
+RdY4zTW2ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQ
+OA7+j0xbm0bqQfWwCHTD0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwv
+JoIQ4uNllAoEwF73XVv4EOLQunpL+943AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08C
+AwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAcYwHQYDVR0O
+BBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IBAQA+0hyJ
+LjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecY
+MnQ8SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ
+44gx+FkagQnIl6Z0x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6I
+Jd1hJyMctTEHBDa0GpC9oHRxUIltvBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNw
+i/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7NzTogVZ96edhBiIL5VaZVDADlN
+9u6wWk5JRFRYX0KD
+-----END CERTIFICATE-----
+
+# Issuer: CN=GeoTrust Primary Certification Authority - G3 O=GeoTrust Inc. OU=(c) 2008 GeoTrust Inc. - For authorized use only
+# Subject: CN=GeoTrust Primary Certification Authority - G3 O=GeoTrust Inc. OU=(c) 2008 GeoTrust Inc. - For authorized use only
+# Label: "GeoTrust Primary Certification Authority - G3"
+# Serial: 28809105769928564313984085209975885599
+# MD5 Fingerprint: b5:e8:34:36:c9:10:44:58:48:70:6d:2e:83:d4:b8:05
+# SHA1 Fingerprint: 03:9e:ed:b8:0b:e7:a0:3c:69:53:89:3b:20:d2:d9:32:3a:4c:2a:fd
+# SHA256 Fingerprint: b4:78:b8:12:25:0d:f8:78:63:5c:2a:a7:ec:7d:15:5e:aa:62:5e:e8:29:16:e2:cd:29:43:61:88:6c:d1:fb:d4
+-----BEGIN CERTIFICATE-----
+MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCB
+mDELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsT
+MChjKSAyMDA4IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s
+eTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhv
+cml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIzNTk1OVowgZgxCzAJ
+BgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg
+MjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0
+BgNVBAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg
+LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz
++uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5jK/BGvESyiaHAKAxJcCGVn2TAppMSAmUm
+hsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdEc5IiaacDiGydY8hS2pgn
+5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3CIShwiP/W
+JmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exAL
+DmKudlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZC
+huOl1UcCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw
+HQYDVR0OBBYEFMR5yo6hTgMdHNxr2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IB
+AQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9cr5HqQ6XErhK8WTTOd8lNNTB
+zU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbEAp7aDHdlDkQN
+kv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD
+AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUH
+SJsMC8tJP33st/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2G
+spki4cErx5z481+oghLrGREt
+-----END CERTIFICATE-----
+
+# Issuer: CN=thawte Primary Root CA - G2 O=thawte, Inc. OU=(c) 2007 thawte, Inc. - For authorized use only
+# Subject: CN=thawte Primary Root CA - G2 O=thawte, Inc. OU=(c) 2007 thawte, Inc. - For authorized use only
+# Label: "thawte Primary Root CA - G2"
+# Serial: 71758320672825410020661621085256472406
+# MD5 Fingerprint: 74:9d:ea:60:24:c4:fd:22:53:3e:cc:3a:72:d9:29:4f
+# SHA1 Fingerprint: aa:db:bc:22:23:8f:c4:01:a1:27:bb:38:dd:f4:1d:db:08:9e:f0:12
+# SHA256 Fingerprint: a4:31:0d:50:af:18:a6:44:71:90:37:2a:86:af:af:8b:95:1f:fb:43:1d:83:7f:1e:56:88:b4:59:71:ed:15:57
+-----BEGIN CERTIFICATE-----
+MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDEL
+MAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMp
+IDIwMDcgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAi
+BgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMjAeFw0wNzExMDUwMDAw
+MDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh
+d3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBGb3Ig
+YXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9v
+dCBDQSAtIEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/
+BebfowJPDQfGAFG6DAJSLSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6
+papu+7qzcMBniKI11KOasf2twu8x+qi58/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8E
+BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUmtgAMADna3+FGO6Lts6K
+DPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUNG4k8VIZ3
+KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41ox
+XZ3Krr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg==
+-----END CERTIFICATE-----
+
+# Issuer: CN=thawte Primary Root CA - G3 O=thawte, Inc. OU=Certification Services Division/(c) 2008 thawte, Inc. - For authorized use only
+# Subject: CN=thawte Primary Root CA - G3 O=thawte, Inc. OU=Certification Services Division/(c) 2008 thawte, Inc. - For authorized use only
+# Label: "thawte Primary Root CA - G3"
+# Serial: 127614157056681299805556476275995414779
+# MD5 Fingerprint: fb:1b:5d:43:8a:94:cd:44:c6:76:f2:43:4b:47:e7:31
+# SHA1 Fingerprint: f1:8b:53:8d:1b:e9:03:b6:a6:f0:56:43:5b:17:15:89:ca:f3:6b:f2
+# SHA256 Fingerprint: 4b:03:f4:58:07:ad:70:f2:1b:fc:2c:ae:71:c9:fd:e4:60:4c:06:4c:f5:ff:b6:86:ba:e5:db:aa:d7:fd:d3:4c
+-----BEGIN CERTIFICATE-----
+MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCB
+rjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
+Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
+MDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNV
+BAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0wODA0MDIwMDAwMDBa
+Fw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3Rl
+LCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9u
+MTgwNgYDVQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXpl
+ZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEcz
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsr8nLPvb2FvdeHsbnndm
+gcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2AtP0LMqmsywCPLLEHd5N/8
+YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC+BsUa0Lf
+b1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS9
+9irY7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2S
+zhkGcuYMXDhpxwTWvGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUk
+OQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV
+HQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJKoZIhvcNAQELBQADggEBABpA
+2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweKA3rD6z8KLFIW
+oCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu
+t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7c
+KUGRIjxpp7sC8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fM
+m7v/OeZWYdMKp8RcTGB7BXcmer/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZu
+MdRAGmI0Nj81Aa6sY6A=
+-----END CERTIFICATE-----
+
+# Issuer: CN=GeoTrust Primary Certification Authority - G2 O=GeoTrust Inc. OU=(c) 2007 GeoTrust Inc. - For authorized use only
+# Subject: CN=GeoTrust Primary Certification Authority - G2 O=GeoTrust Inc. OU=(c) 2007 GeoTrust Inc. - For authorized use only
+# Label: "GeoTrust Primary Certification Authority - G2"
+# Serial: 80682863203381065782177908751794619243
+# MD5 Fingerprint: 01:5e:d8:6b:bd:6f:3d:8e:a1:31:f8:12:e0:98:73:6a
+# SHA1 Fingerprint: 8d:17:84:d5:37:f3:03:7d:ec:70:fe:57:8b:51:9a:99:e6:10:d7:b0
+# SHA256 Fingerprint: 5e:db:7a:c4:3b:82:a0:6a:87:61:e8:d7:be:49:79:eb:f2:61:1f:7d:d7:9b:f9:1c:1c:6b:56:6a:21:9e:d7:66
+-----BEGIN CERTIFICATE-----
+MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDEL
+MAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChj
+KSAyMDA3IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2
+MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
+eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1OVowgZgxCzAJBgNV
+BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykgMjAw
+NyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNV
+BAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH
+MjB2MBAGByqGSM49AgEGBSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcL
+So17VDs6bl8VAsBQps8lL33KSLjHUGMcKiEIfJo22Av+0SbFWDEwKCXzXV2juLal
+tJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO
+BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+EVXVMAoG
+CCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGT
+qQ7mndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBucz
+rD6ogRLQy7rQkgu2npaqBA+K
+-----END CERTIFICATE-----
+
+# Issuer: CN=VeriSign Universal Root Certification Authority O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2008 VeriSign, Inc. - For authorized use only
+# Subject: CN=VeriSign Universal Root Certification Authority O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2008 VeriSign, Inc. - For authorized use only
+# Label: "VeriSign Universal Root Certification Authority"
+# Serial: 85209574734084581917763752644031726877
+# MD5 Fingerprint: 8e:ad:b5:01:aa:4d:81:e4:8c:1d:d1:e1:14:00:95:19
+# SHA1 Fingerprint: 36:79:ca:35:66:87:72:30:4d:30:a5:fb:87:3b:0f:a7:7b:b7:0d:54
+# SHA256 Fingerprint: 23:99:56:11:27:a5:71:25:de:8c:ef:ea:61:0d:df:2f:a0:78:b5:c8:06:7f:4e:82:82:90:bf:b8:60:e8:4b:3c
+-----BEGIN CERTIFICATE-----
+MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCB
+vTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
+ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJp
+U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MTgwNgYDVQQDEy9W
+ZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe
+Fw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJVUzEX
+MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0
+IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9y
+IGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNh
+bCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF
+AAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj1mCOkdeQmIN65lgZOIzF
+9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGPMiJhgsWH
+H26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+H
+LL729fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN
+/BMReYTtXlT2NJ8IAfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPT
+rJ9VAMf2CGqUuV/c4DPxhGD5WycRtPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1Ud
+EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0GCCsGAQUFBwEMBGEwX6FdoFsw
+WTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2Oa8PPgGrUSBgs
+exkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud
+DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4
+sAPmLGd75JR3Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+
+seQxIcaBlVZaDrHC1LGmWazxY8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz
+4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTxP/jgdFcrGJ2BtMQo2pSXpXDrrB2+
+BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+PwGZsY6rp2aQW9IHR
+lRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4mJO3
+7M2CYfE45k+XmCpajQ==
+-----END CERTIFICATE-----
+
+# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G4 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2007 VeriSign, Inc. - For authorized use only
+# Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G4 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2007 VeriSign, Inc. - For authorized use only
+# Label: "VeriSign Class 3 Public Primary Certification Authority - G4"
+# Serial: 63143484348153506665311985501458640051
+# MD5 Fingerprint: 3a:52:e1:e7:fd:6f:3a:e3:6f:f3:6f:99:1b:f9:22:41
+# SHA1 Fingerprint: 22:d5:d8:df:8f:02:31:d1:8d:f7:9d:b7:cf:8a:2d:64:c9:3f:6c:3a
+# SHA256 Fingerprint: 69:dd:d7:ea:90:bb:57:c9:3e:13:5d:c8:5e:a6:fc:d5:48:0b:60:32:39:bd:c4:54:fc:75:8b:2a:26:cf:7f:79
+-----BEGIN CERTIFICATE-----
+MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjEL
+MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
+ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2ln
+biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp
+U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y
+aXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjELMAkG
+A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJp
+U2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwg
+SW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2ln
+biBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5
+IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8Utpkmw4tXNherJI9/gHm
+GUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGzrl0Bp3ve
+fLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUw
+AwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJ
+aW1hZ2UvZ2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYj
+aHR0cDovL2xvZ28udmVyaXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMW
+kf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMDA2gAMGUCMGYhDBgmYFo4e1ZC
+4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIxAJw9SDkjOVga
+FRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA==
+-----END CERTIFICATE-----
+
+# Issuer: CN=NetLock Arany (Class Gold) Főtanúsítvány O=NetLock Kft. OU=Tanúsítványkiadók (Certification Services)
+# Subject: CN=NetLock Arany (Class Gold) Főtanúsítvány O=NetLock Kft. OU=Tanúsítványkiadók (Certification Services)
+# Label: "NetLock Arany (Class Gold) Főtanúsítvány"
+# Serial: 80544274841616
+# MD5 Fingerprint: c5:a1:b7:ff:73:dd:d6:d7:34:32:18:df:fc:3c:ad:88
+# SHA1 Fingerprint: 06:08:3f:59:3f:15:a1:04:a0:69:a4:6b:a9:03:d0:06:b7:97:09:91
+# SHA256 Fingerprint: 6c:61:da:c3:a2:de:f0:31:50:6b:e0:36:d2:a6:fe:40:19:94:fb:d1:3d:f9:c8:d4:66:59:92:74:c4:46:ec:98
+-----BEGIN CERTIFICATE-----
+MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQG
+EwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3
+MDUGA1UECwwuVGFuw7pzw610dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNl
+cnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBBcmFueSAoQ2xhc3MgR29sZCkgRsWR
+dGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgxMjA2MTUwODIxWjCB
+pzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxOZXRM
+b2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlm
+aWNhdGlvbiBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNz
+IEdvbGQpIEbFkXRhbsO6c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
+MIIBCgKCAQEAxCRec75LbRTDofTjl5Bu0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrT
+lF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw/HpYzY6b7cNGbIRwXdrz
+AZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAkH3B5r9s5
+VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRG
+ILdwfzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2
+BJtr+UBdADTHLpl1neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAG
+AQH/AgEEMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2M
+U9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwWqZw8UQCgwBEIBaeZ5m8BiFRh
+bvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTtaYtOUZcTh5m2C
++C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC
+bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2F
+uLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2
+XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E=
+-----END CERTIFICATE-----
+
+# Issuer: CN=Staat der Nederlanden Root CA - G2 O=Staat der Nederlanden
+# Subject: CN=Staat der Nederlanden Root CA - G2 O=Staat der Nederlanden
+# Label: "Staat der Nederlanden Root CA - G2"
+# Serial: 10000012
+# MD5 Fingerprint: 7c:a5:0f:f8:5b:9a:7d:6d:30:ae:54:5a:e3:42:a2:8a
+# SHA1 Fingerprint: 59:af:82:79:91:86:c7:b4:75:07:cb:cf:03:57:46:eb:04:dd:b7:16
+# SHA256 Fingerprint: 66:8c:83:94:7d:a6:3b:72:4b:ec:e1:74:3c:31:a0:e6:ae:d0:db:8e:c5:b3:1b:e3:77:bb:78:4f:91:b6:71:6f
+-----BEGIN CERTIFICATE-----
+MIIFyjCCA7KgAwIBAgIEAJiWjDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO
+TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh
+dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEcyMB4XDTA4MDMyNjExMTgxN1oX
+DTIwMDMyNTExMDMxMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl
+ciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv
+b3QgQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMVZ5291
+qj5LnLW4rJ4L5PnZyqtdj7U5EILXr1HgO+EASGrP2uEGQxGZqhQlEq0i6ABtQ8Sp
+uOUfiUtnvWFI7/3S4GCI5bkYYCjDdyutsDeqN95kWSpGV+RLufg3fNU254DBtvPU
+Z5uW6M7XxgpT0GtJlvOjCwV3SPcl5XCsMBQgJeN/dVrlSPhOewMHBPqCYYdu8DvE
+pMfQ9XQ+pV0aCPKbJdL2rAQmPlU6Yiile7Iwr/g3wtG61jj99O9JMDeZJiFIhQGp
+5Rbn3JBV3w/oOM2ZNyFPXfUib2rFEhZgF1XyZWampzCROME4HYYEhLoaJXhena/M
+UGDWE4dS7WMfbWV9whUYdMrhfmQpjHLYFhN9C0lK8SgbIHRrxT3dsKpICT0ugpTN
+GmXZK4iambwYfp/ufWZ8Pr2UuIHOzZgweMFvZ9C+X+Bo7d7iscksWXiSqt8rYGPy
+5V6548r6f1CGPqI0GAwJaCgRHOThuVw+R7oyPxjMW4T182t0xHJ04eOLoEq9jWYv
+6q012iDTiIJh8BIitrzQ1aTsr1SIJSQ8p22xcik/Plemf1WvbibG/ufMQFxRRIEK
+eN5KzlW/HdXZt1bv8Hb/C3m1r737qWmRRpdogBQ2HbN/uymYNqUg+oJgYjOk7Na6
+B6duxc8UpufWkjTYgfX8HV2qXB72o007uPc5AgMBAAGjgZcwgZQwDwYDVR0TAQH/
+BAUwAwEB/zBSBgNVHSAESzBJMEcGBFUdIAAwPzA9BggrBgEFBQcCARYxaHR0cDov
+L3d3dy5wa2lvdmVyaGVpZC5ubC9wb2xpY2llcy9yb290LXBvbGljeS1HMjAOBgNV
+HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJFoMocVHYnitfGsNig0jQt8YojrMA0GCSqG
+SIb3DQEBCwUAA4ICAQCoQUpnKpKBglBu4dfYszk78wIVCVBR7y29JHuIhjv5tLyS
+CZa59sCrI2AGeYwRTlHSeYAz+51IvuxBQ4EffkdAHOV6CMqqi3WtFMTC6GY8ggen
+5ieCWxjmD27ZUD6KQhgpxrRW/FYQoAUXvQwjf/ST7ZwaUb7dRUG/kSS0H4zpX897
+IZmflZ85OkYcbPnNe5yQzSipx6lVu6xiNGI1E0sUOlWDuYaNkqbG9AclVMwWVxJK
+gnjIFNkXgiYtXSAfea7+1HAWFpWD2DU5/1JddRwWxRNVz0fMdWVSSt7wsKfkCpYL
++63C4iWEst3kvX5ZbJvw8NjnyvLplzh+ib7M+zkXYT9y2zqR2GUBGR2tUKRXCnxL
+vJxxcypFURmFzI79R6d0lR2o0a9OF7FpJsKqeFdbxU2n5Z4FF5TKsl+gSRiNNOkm
+bEgeqmiSBeGCc1qb3AdbCG19ndeNIdn8FCCqwkXfP+cAslHkwvgFuXkajDTznlvk
+N1trSt8sV4pAWja63XVECDdCcAz+3F4hoKOKwJCcaNpQ5kUQR3i2TtJlycM33+FC
+Y7BXN0Ute4qcvwXqZVUz9zkQxSgqIXobisQk+T8VyJoVIPVVYpbtbZNQvOSqeK3Z
+ywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm66+KAQ==
+-----END CERTIFICATE-----
+
+# Issuer: CN=Hongkong Post Root CA 1 O=Hongkong Post
+# Subject: CN=Hongkong Post Root CA 1 O=Hongkong Post
+# Label: "Hongkong Post Root CA 1"
+# Serial: 1000
+# MD5 Fingerprint: a8:0d:6f:39:78:b9:43:6d:77:42:6d:98:5a:cc:23:ca
+# SHA1 Fingerprint: d6:da:a8:20:8d:09:d2:15:4d:24:b5:2f:cb:34:6e:b2:58:b2:8a:58
+# SHA256 Fingerprint: f9:e6:7d:33:6c:51:00:2a:c0:54:c6:32:02:2d:66:dd:a2:e7:e3:ff:f1:0a:d0:61:ed:31:d8:bb:b4:10:cf:b2
+-----BEGIN CERTIFICATE-----
+MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsx
+FjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3Qg
+Um9vdCBDQSAxMB4XDTAzMDUxNTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkG
+A1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdr
+b25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
+AQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1ApzQ
+jVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEn
+PzlTCeqrauh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjh
+ZY4bXSNmO7ilMlHIhqqhqZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9
+nnV0ttgCXjqQesBCNnLsak3c78QA3xMYV18meMjWCnl3v/evt3a5pQuEF10Q6m/h
+q5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNVHRMBAf8ECDAGAQH/AgED
+MA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7ih9legYsC
+mEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI3
+7piol7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clB
+oiMBdDhViw+5LmeiIAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJs
+EhTkYY2sEJCehFC78JZvRZ+K88psT/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpO
+fMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilTc4afU9hDDl3WY4JxHYB0yvbi
+AmvZWg==
+-----END CERTIFICATE-----
+
+# Issuer: CN=SecureSign RootCA11 O=Japan Certification Services, Inc.
+# Subject: CN=SecureSign RootCA11 O=Japan Certification Services, Inc.
+# Label: "SecureSign RootCA11"
+# Serial: 1
+# MD5 Fingerprint: b7:52:74:e2:92:b4:80:93:f2:75:e4:cc:d7:f2:ea:26
+# SHA1 Fingerprint: 3b:c4:9f:48:f8:f3:73:a0:9c:1e:bd:f8:5b:b1:c3:65:c7:d8:11:b3
+# SHA256 Fingerprint: bf:0f:ee:fb:9e:3a:58:1a:d5:f9:e9:db:75:89:98:57:43:d2:61:08:5c:4d:31:4f:6f:5d:72:59:aa:42:16:12
+-----BEGIN CERTIFICATE-----
+MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDEr
+MCkGA1UEChMiSmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoG
+A1UEAxMTU2VjdXJlU2lnbiBSb290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0
+MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSswKQYDVQQKEyJKYXBhbiBDZXJ0aWZp
+Y2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1cmVTaWduIFJvb3RD
+QTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvLTJsz
+i1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8
+h9uuywGOwvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOV
+MdrAG/LuYpmGYz+/3ZMqg6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9
+UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rPO7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni
+8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitAbpSACW22s293bzUIUPsC
+h8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZXt94wDgYD
+VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEB
+AKChOBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xm
+KbabfSVSSUOrTC4rbnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQ
+X5Ucv+2rIrVls4W6ng+4reV6G4pQOh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWr
+QbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01y8hSyn+B/tlr0/cR7SXf+Of5
+pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061lgeLKBObjBmN
+QSdJQO7e5iNEOdyhIta6A/I=
+-----END CERTIFICATE-----
+
+# Issuer: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd.
+# Subject: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd.
+# Label: "Microsec e-Szigno Root CA 2009"
+# Serial: 14014712776195784473
+# MD5 Fingerprint: f8:49:f4:03:bc:44:2d:83:be:48:69:7d:29:64:fc:b1
+# SHA1 Fingerprint: 89:df:74:fe:5c:f4:0f:4a:80:f9:e3:37:7d:54:da:91:e1:01:31:8e
+# SHA256 Fingerprint: 3c:5f:81:fe:a5:fa:b8:2c:64:bf:a2:ea:ec:af:cd:e8:e0:77:fc:86:20:a7:ca:e5:37:16:3d:f3:6e:db:f3:78
+-----BEGIN CERTIFICATE-----
+MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYD
+VQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0
+ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0G
+CSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTAeFw0wOTA2MTYxMTMwMThaFw0y
+OTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3Qx
+FjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3pp
+Z25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o
+dTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvP
+kd6mJviZpWNwrZuuyjNAfW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tc
+cbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG0IMZfcChEhyVbUr02MelTTMuhTlAdX4U
+fIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKApxn1ntxVUwOXewdI/5n7
+N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm1HxdrtbC
+xkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1
++rUCAwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G
+A1UdDgQWBBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPM
+Pcu1SCOhGnqmKrs0aDAbBgNVHREEFDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqG
+SIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0olZMEyL/azXm4Q5DwpL7v8u8h
+mLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfXI/OMn74dseGk
+ddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775
+tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c
+2Pm2G2JwCz02yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5t
+HMN1Rq41Bab2XD0h7lbwyYIiLXpUq3DDfSJlgnCW
+-----END CERTIFICATE-----
+
+# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3
+# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3
+# Label: "GlobalSign Root CA - R3"
+# Serial: 4835703278459759426209954
+# MD5 Fingerprint: c5:df:b8:49:ca:05:13:55:ee:2d:ba:1a:c3:3e:b0:28
+# SHA1 Fingerprint: d6:9b:56:11:48:f0:1c:77:c5:45:78:c1:09:26:df:5b:85:69:76:ad
+# SHA256 Fingerprint: cb:b5:22:d7:b7:f1:27:ad:6a:01:13:86:5b:df:1c:d4:10:2e:7d:07:59:af:63:5a:7c:f4:72:0d:c9:63:c5:3b
+-----BEGIN CERTIFICATE-----
+MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G
+A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp
+Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4
+MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG
+A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8
+RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT
+gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm
+KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd
+QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ
+XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw
+DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o
+LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU
+RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp
+jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK
+6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX
+mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs
+Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH
+WD9f
+-----END CERTIFICATE-----
+
+# Issuer: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068
+# Subject: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068
+# Label: "Autoridad de Certificacion Firmaprofesional CIF A62634068"
+# Serial: 6047274297262753887
+# MD5 Fingerprint: 73:3a:74:7a:ec:bb:a3:96:a6:c2:e4:e2:c8:9b:c0:c3
+# SHA1 Fingerprint: ae:c5:fb:3f:c8:e1:bf:c4:e5:4f:03:07:5a:9a:e8:00:b7:f7:b6:fa
+# SHA256 Fingerprint: 04:04:80:28:bf:1f:28:64:d4:8f:9a:d4:d8:32:94:36:6a:82:88:56:55:3f:3b:14:30:3f:90:14:7f:5d:40:ef
+-----BEGIN CERTIFICATE-----
+MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UE
+BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h
+cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEy
+MzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg
+Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi
+MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9
+thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM
+cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG
+L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i
+NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h
+X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b
+m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy
+Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja
+EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T
+KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF
+6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh
+OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYD
+VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNHDhpkLzCBpgYD
+VR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp
+cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBv
+ACAAZABlACAAbABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBl
+AGwAbwBuAGEAIAAwADgAMAAxADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF
+661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx51tkljYyGOylMnfX40S2wBEqgLk9
+am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qkR71kMrv2JYSiJ0L1
+ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaPT481
+PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS
+3a/DTg4fJl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5k
+SeTy36LssUzAKh3ntLFlosS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF
+3dvd6qJ2gHN99ZwExEWN57kci57q13XRcrHedUTnQn3iV2t93Jm8PYMo6oCTjcVM
+ZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoRsaS8I8nkvof/uZS2+F0g
+StRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTDKCOM/icz
+Q0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQB
+jLMi6Et8Vcad+qMUu2WFbm5PEn4KPJ2V
+-----END CERTIFICATE-----
+
+# Issuer: CN=Izenpe.com O=IZENPE S.A.
+# Subject: CN=Izenpe.com O=IZENPE S.A.
+# Label: "Izenpe.com"
+# Serial: 917563065490389241595536686991402621
+# MD5 Fingerprint: a6:b0:cd:85:80:da:5c:50:34:a3:39:90:2f:55:67:73
+# SHA1 Fingerprint: 2f:78:3d:25:52:18:a7:4a:65:39:71:b5:2c:a2:9c:45:15:6f:e9:19
+# SHA256 Fingerprint: 25:30:cc:8e:98:32:15:02:ba:d9:6f:9b:1f:ba:1b:09:9e:2d:29:9e:0f:45:48:bb:91:4f:36:3b:c0:d4:53:1f
+-----BEGIN CERTIFICATE-----
+MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4
+MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6
+ZW5wZS5jb20wHhcNMDcxMjEzMTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYD
+VQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5j
+b20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ03rKDx6sp4boFmVq
+scIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAKClaO
+xdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6H
+LmYRY2xU+zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFX
+uaOKmMPsOzTFlUFpfnXCPCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQD
+yCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxTOTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+
+JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbKF7jJeodWLBoBHmy+E60Q
+rLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK0GqfvEyN
+BjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8L
+hij+0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIB
+QFqNeb+Lz0vPqhbBleStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+
+HMh3/1uaD7euBUbl8agW7EekFwIDAQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2lu
+Zm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+SVpFTlBFIFMuQS4gLSBDSUYg
+QTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBGNjIgUzgxQzBB
+BgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx
+MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
+AQYwHQYDVR0OBBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUA
+A4ICAQB4pgwWSp9MiDrAyw6lFn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWb
+laQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbgakEyrkgPH7UIBzg/YsfqikuFgba56
+awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8qhT/AQKM6WfxZSzwo
+JNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Csg1lw
+LDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCT
+VyvehQP5aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGk
+LhObNA5me0mrZJfQRsN5nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJb
+UjWumDqtujWTI6cfSN01RpiyEGjkpTHCClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/
+QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZoQ0iy2+tzJOeRf1SktoA+
+naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1ZWrOZyGls
+QyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw==
+-----END CERTIFICATE-----
+
+# Issuer: CN=Chambers of Commerce Root - 2008 O=AC Camerfirma S.A.
+# Subject: CN=Chambers of Commerce Root - 2008 O=AC Camerfirma S.A.
+# Label: "Chambers of Commerce Root - 2008"
+# Serial: 11806822484801597146
+# MD5 Fingerprint: 5e:80:9e:84:5a:0e:65:0b:17:02:f3:55:18:2a:3e:d7
+# SHA1 Fingerprint: 78:6a:74:ac:76:ab:14:7f:9c:6a:30:50:ba:9e:a8:7e:fe:9a:ce:3c
+# SHA256 Fingerprint: 06:3e:4a:fa:c4:91:df:d3:32:f3:08:9b:85:42:e9:46:17:d8:93:d7:fe:94:4e:10:a7:93:7e:e2:9d:96:93:c0
+-----BEGIN CERTIFICATE-----
+MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYD
+VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0
+IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3
+MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xKTAnBgNVBAMTIENoYW1iZXJz
+IG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEyMjk1MFoXDTM4MDcz
+MTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBj
+dXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIw
+EAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEp
+MCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0G
+CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW9
+28sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKAXuFixrYp4YFs8r/lfTJq
+VKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorjh40G072Q
+DuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR
+5gN/ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfL
+ZEFHcpOrUMPrCXZkNNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05a
+Sd+pZgvMPMZ4fKecHePOjlO+Bd5gD2vlGts/4+EhySnB8esHnFIbAURRPHsl18Tl
+UlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331lubKgdaX8ZSD6e2wsWsSaR6s
++12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ0wlf2eOKNcx5
+Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj
+ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAx
+hduub+84Mxh2EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNV
+HQ4EFgQU+SSsD7K1+HnA+mCIG8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1
++HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpN
+YWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29t
+L2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVy
+ZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAt
+IDIwMDiCCQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRV
+HSAAMCowKAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20w
+DQYJKoZIhvcNAQEFBQADggIBAJASryI1wqM58C7e6bXpeHxIvj99RZJe6dqxGfwW
+PJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH3qLPaYRgM+gQDROpI9CF
+5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbURWpGqOt1
+glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaH
+FoI6M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2
+pSB7+R5KBWIBpih1YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MD
+xvbxrN8y8NmBGuScvfaAFPDRLLmF9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QG
+tjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcKzBIKinmwPQN/aUv0NCB9szTq
+jktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvGnrDQWzilm1De
+fhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg
+OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZ
+d0jQ
+-----END CERTIFICATE-----
+
+# Issuer: CN=Global Chambersign Root - 2008 O=AC Camerfirma S.A.
+# Subject: CN=Global Chambersign Root - 2008 O=AC Camerfirma S.A.
+# Label: "Global Chambersign Root - 2008"
+# Serial: 14541511773111788494
+# MD5 Fingerprint: 9e:80:ff:78:01:0c:2e:c1:36:bd:fe:96:90:6e:08:f3
+# SHA1 Fingerprint: 4a:bd:ee:ec:95:0d:35:9c:89:ae:c7:52:a1:2c:5b:29:f6:d6:aa:0c
+# SHA256 Fingerprint: 13:63:35:43:93:34:a7:69:80:16:a0:d3:24:de:72:28:4e:07:9d:7b:52:20:bb:8f:bd:74:78:16:ee:be:ba:ca
+-----BEGIN CERTIFICATE-----
+MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYD
+VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0
+IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3
+MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD
+aGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMxNDBaFw0zODA3MzEx
+MjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3Vy
+cmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAG
+A1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAl
+BgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZI
+hvcNAQEBBQADggIPADCCAgoCggIBAMDfVtPkOpt2RbQT2//BthmLN0EYlVJH6xed
+KYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXfXjaOcNFccUMd2drvXNL7
+G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0ZJJ0YPP2
+zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4
+ddPB/gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyG
+HoiMvvKRhI9lNNgATH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2
+Id3UwD2ln58fQ1DJu7xsepeY7s2MH/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3V
+yJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfeOx2YItaswTXbo6Al/3K1dh3e
+beksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSFHTynyQbehP9r
+6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh
+wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsog
+zCtLkykPAgMBAAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQW
+BBS5CcqcHtvTbDprru1U8VuTBjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDpr
+ru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UEBhMCRVUxQzBBBgNVBAcTOk1hZHJp
+ZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJmaXJtYS5jb20vYWRk
+cmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJmaXJt
+YSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiC
+CQDJzdPp1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCow
+KAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZI
+hvcNAQEFBQADggIBAICIf3DekijZBZRG/5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZ
+UohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6ReAJ3spED8IXDneRRXoz
+X1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/sdZ7LoR/x
+fxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVz
+a2Mg9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yyd
+Yhz2rXzdpjEetrHHfoUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMd
+SqlapskD7+3056huirRXhOukP9DuqqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9O
+AP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETrP3iZ8ntxPjzxmKfFGBI/5rso
+M0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVqc5iJWzouE4ge
+v8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z
+09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B
+-----END CERTIFICATE-----
+
+# Issuer: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc.
+# Subject: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc.
+# Label: "Go Daddy Root Certificate Authority - G2"
+# Serial: 0
+# MD5 Fingerprint: 80:3a:bc:22:c1:e6:fb:8d:9b:3b:27:4a:32:1b:9a:01
+# SHA1 Fingerprint: 47:be:ab:c9:22:ea:e8:0e:78:78:34:62:a7:9f:45:c2:54:fd:e6:8b
+# SHA256 Fingerprint: 45:14:0b:32:47:eb:9c:c8:c5:b4:f0:d7:b5:30:91:f7:32:92:08:9e:6e:5a:63:e2:74:9d:d3:ac:a9:19:8e:da
+-----BEGIN CERTIFICATE-----
+MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx
+EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT
+EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp
+ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz
+NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH
+EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE
+AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw
+DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD
+E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH
+/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy
+DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh
+GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR
+tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA
+AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE
+FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX
+WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu
+9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr
+gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo
+2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO
+LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI
+4uJEvlz36hz1
+-----END CERTIFICATE-----
+
+# Issuer: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc.
+# Subject: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc.
+# Label: "Starfield Root Certificate Authority - G2"
+# Serial: 0
+# MD5 Fingerprint: d6:39:81:c6:52:7e:96:69:fc:fc:ca:66:ed:05:f2:96
+# SHA1 Fingerprint: b5:1c:06:7c:ee:2b:0c:3d:f8:55:ab:2d:92:f4:fe:39:d4:e7:0f:0e
+# SHA256 Fingerprint: 2c:e1:cb:0b:f9:d2:f9:e1:02:99:3f:be:21:51:52:c3:b2:dd:0c:ab:de:1c:68:e5:31:9b:83:91:54:db:b7:f5
+-----BEGIN CERTIFICATE-----
+MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx
+EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
+HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs
+ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw
+MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6
+b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj
+aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp
+Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
+ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg
+nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1
+HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N
+Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN
+dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0
+HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO
+BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G
+CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU
+sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3
+4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg
+8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K
+pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1
+mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0
+-----END CERTIFICATE-----
+
+# Issuer: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc.
+# Subject: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc.
+# Label: "Starfield Services Root Certificate Authority - G2"
+# Serial: 0
+# MD5 Fingerprint: 17:35:74:af:7b:61:1c:eb:f4:f9:3c:e2:ee:40:f9:a2
+# SHA1 Fingerprint: 92:5a:8f:8d:2c:6d:04:e0:66:5f:59:6a:ff:22:d8:63:e8:25:6f:3f
+# SHA256 Fingerprint: 56:8d:69:05:a2:c8:87:08:a4:b3:02:51:90:ed:cf:ed:b1:97:4a:60:6a:13:c6:e5:29:0f:cb:2a:e6:3e:da:b5
+-----BEGIN CERTIFICATE-----
+MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx
+EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
+HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs
+ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5
+MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD
+VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy
+ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy
+dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p
+OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2
+8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K
+Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe
+hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk
+6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw
+DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q
+AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI
+bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB
+ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z
+qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd
+iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn
+0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN
+sSi6
+-----END CERTIFICATE-----
+
+# Issuer: CN=AffirmTrust Commercial O=AffirmTrust
+# Subject: CN=AffirmTrust Commercial O=AffirmTrust
+# Label: "AffirmTrust Commercial"
+# Serial: 8608355977964138876
+# MD5 Fingerprint: 82:92:ba:5b:ef:cd:8a:6f:a6:3d:55:f9:84:f6:d6:b7
+# SHA1 Fingerprint: f9:b5:b6:32:45:5f:9c:be:ec:57:5f:80:dc:e9:6e:2c:c7:b2:78:b7
+# SHA256 Fingerprint: 03:76:ab:1d:54:c5:f9:80:3c:e4:b2:e2:01:a0:ee:7e:ef:7b:57:b6:36:e8:a9:3c:9b:8d:48:60:c9:6f:5f:a7
+-----BEGIN CERTIFICATE-----
+MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UE
+BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz
+dCBDb21tZXJjaWFsMB4XDTEwMDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDEL
+MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp
+cm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
+AQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6EqdbDuKP
+Hx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yr
+ba0F8PrVC8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPAL
+MeIrJmqbTFeurCA+ukV6BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1
+yHp52UKqK39c/s4mT6NmgTWvRLpUHhwwMmWd5jyTXlBOeuM61G7MGvv50jeuJCqr
+VwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNVHQ4EFgQUnZPGU4teyq8/
+nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ
+KoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYG
+XUPGhi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNj
+vbz4YYCanrHOQnDiqX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivt
+Z8SOyUOyXGsViQK8YvxO8rUzqrJv0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9g
+N53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0khsUlHRUe072o0EclNmsxZt9YC
+nlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8=
+-----END CERTIFICATE-----
+
+# Issuer: CN=AffirmTrust Networking O=AffirmTrust
+# Subject: CN=AffirmTrust Networking O=AffirmTrust
+# Label: "AffirmTrust Networking"
+# Serial: 8957382827206547757
+# MD5 Fingerprint: 42:65:ca:be:01:9a:9a:4c:a9:8c:41:49:cd:c0:d5:7f
+# SHA1 Fingerprint: 29:36:21:02:8b:20:ed:02:f5:66:c5:32:d1:d6:ed:90:9f:45:00:2f
+# SHA256 Fingerprint: 0a:81:ec:5a:92:97:77:f1:45:90:4a:f3:8d:5d:50:9f:66:b5:e2:c5:8f:cd:b5:31:05:8b:0e:17:f3:f0:b4:1b
+-----BEGIN CERTIFICATE-----
+MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UE
+BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz
+dCBOZXR3b3JraW5nMB4XDTEwMDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDEL
+MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp
+cm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
+AQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SEHi3y
+YJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbua
+kCNrmreIdIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRL
+QESxG9fhwoXA3hA/Pe24/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp
+6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gbh+0t+nvujArjqWaJGctB+d1ENmHP4ndG
+yH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNVHQ4EFgQUBx/S55zawm6i
+QLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ
+KoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfO
+tDIuUFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzu
+QY0x2+c06lkh1QF612S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZ
+Lgo/bNjR9eUJtGxUAArgFU2HdW23WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4u
+olu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9/ZFvgrG+CJPbFEfxojfHRZ48
+x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s=
+-----END CERTIFICATE-----
+
+# Issuer: CN=AffirmTrust Premium O=AffirmTrust
+# Subject: CN=AffirmTrust Premium O=AffirmTrust
+# Label: "AffirmTrust Premium"
+# Serial: 7893706540734352110
+# MD5 Fingerprint: c4:5d:0e:48:b6:ac:28:30:4e:0a:bc:f9:38:16:87:57
+# SHA1 Fingerprint: d8:a6:33:2c:e0:03:6f:b1:85:f6:63:4f:7d:6a:06:65:26:32:28:27
+# SHA256 Fingerprint: 70:a7:3f:7f:37:6b:60:07:42:48:90:45:34:b1:14:82:d5:bf:0e:69:8e:cc:49:8d:f5:25:77:eb:f2:e9:3b:9a
+-----BEGIN CERTIFICATE-----
+MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UE
+BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVz
+dCBQcmVtaXVtMB4XDTEwMDEyOTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkG
+A1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1U
+cnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxBLf
+qV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtnBKAQ
+JG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ
++jjeRFcV5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrS
+s8PhaJyJ+HoAVt70VZVs+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5
+HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmdGPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d7
+70O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5Rp9EixAqnOEhss/n/fauG
+V+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NIS+LI+H+S
+qHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S
+5u046uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4Ia
+C1nEWTJ3s7xgaVY5/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TX
+OwF0lkLgAOIua+rF7nKsu7/+6qqo+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYE
+FJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/
+BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByvMiPIs0laUZx2
+KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg
+Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B
+8OWycvpEgjNC6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQ
+MKSOyARiqcTtNd56l+0OOF6SL5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc
+0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK+4w1IX2COPKpVJEZNZOUbWo6xbLQ
+u4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmVBtWVyuEklut89pMF
+u+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFgIxpH
+YoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8
+GKa1qF60g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaO
+RtGdFNrHF+QFlozEJLUbzxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6e
+KeC2uAloGRwYQw==
+-----END CERTIFICATE-----
+
+# Issuer: CN=AffirmTrust Premium ECC O=AffirmTrust
+# Subject: CN=AffirmTrust Premium ECC O=AffirmTrust
+# Label: "AffirmTrust Premium ECC"
+# Serial: 8401224907861490260
+# MD5 Fingerprint: 64:b0:09:55:cf:b1:d5:99:e2:be:13:ab:a6:5d:ea:4d
+# SHA1 Fingerprint: b8:23:6b:00:2f:1d:16:86:53:01:55:6c:11:a4:37:ca:eb:ff:c3:bb
+# SHA256 Fingerprint: bd:71:fd:f6:da:97:e4:cf:62:d1:64:7a:dd:25:81:b0:7d:79:ad:f8:39:7e:b4:ec:ba:9c:5e:84:88:82:14:23
+-----BEGIN CERTIFICATE-----
+MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMC
+VVMxFDASBgNVBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQ
+cmVtaXVtIEVDQzAeFw0xMDAxMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJ
+BgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwXQWZmaXJt
+VHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNMF4bFZ0D
+0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQN8O9
+ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0G
+A1UdDgQWBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4G
+A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/Vs
+aobgxCd05DhT1wV/GzTjxi+zygk8N53X57hG8f2h4nECMEJZh0PUUd+60wkyWs6I
+flc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKMeQ==
+-----END CERTIFICATE-----
+
+# Issuer: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority
+# Subject: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority
+# Label: "Certum Trusted Network CA"
+# Serial: 279744
+# MD5 Fingerprint: d5:e9:81:40:c5:18:69:fc:46:2c:89:75:62:0f:aa:78
+# SHA1 Fingerprint: 07:e0:32:e0:20:b7:2c:3f:19:2f:06:28:a2:59:3a:19:a7:0f:06:9e
+# SHA256 Fingerprint: 5c:58:46:8d:55:f5:8e:49:7e:74:39:82:d2:b5:00:10:b6:d1:65:37:4a:cf:83:a7:d4:a3:2d:b7:68:c4:40:8e
+-----BEGIN CERTIFICATE-----
+MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM
+MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D
+ZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU
+cnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIyMTIwNzM3WhcNMjkxMjMxMTIwNzM3
+WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMg
+Uy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSIw
+IAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rH
+UV+rpDKmYYe2bg+G0jACl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LM
+TXPb865Px1bVWqeWifrzq2jUI4ZZJ88JJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVU
+BBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4fOQtf/WsX+sWn7Et0brM
+kUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0cvW0QM8x
+AcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNV
+HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNV
+HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15y
+sHhE49wcrwn9I0j6vSrEuVUEtRCjjSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfL
+I9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8
+J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY
+VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI
+03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw=
+-----END CERTIFICATE-----
+
+# Issuer: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA
+# Subject: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA
+# Label: "TWCA Root Certification Authority"
+# Serial: 1
+# MD5 Fingerprint: aa:08:8f:f6:f9:7b:b7:f2:b1:a7:1e:9b:ea:ea:bd:79
+# SHA1 Fingerprint: cf:9e:87:6d:d3:eb:fc:42:26:97:a3:b5:a3:7a:a0:76:a9:06:23:48
+# SHA256 Fingerprint: bf:d8:8f:e1:10:1c:41:ae:3e:80:1b:f8:be:56:35:0e:e9:ba:d1:a6:b9:bd:51:5e:dc:5c:6d:5b:87:11:ac:44
+-----BEGIN CERTIFICATE-----
+MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzES
+MBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFU
+V0NBIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMz
+WhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJVEFJV0FO
+LUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlm
+aWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
+AQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFE
+AcK0HMMxQhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HH
+K3XLfJ+utdGdIzdjp9xCoi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeX
+RfwZVzsrb+RH9JlF/h3x+JejiB03HFyP4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/z
+rX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1ry+UPizgN7gr8/g+YnzAx
+3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
+HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkq
+hkiG9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeC
+MErJk/9q56YAf4lCmtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdls
+XebQ79NqZp4VKIV66IIArB6nCWlWQtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62D
+lhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVYT0bf+215WfKEIlKuD8z7fDvn
+aspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocnyYh0igzyXxfkZ
+YiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw==
+-----END CERTIFICATE-----
+
+# Issuer: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2
+# Subject: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2
+# Label: "Security Communication RootCA2"
+# Serial: 0
+# MD5 Fingerprint: 6c:39:7d:a4:0e:55:59:b2:3f:d6:41:b1:12:50:de:43
+# SHA1 Fingerprint: 5f:3b:8c:f2:f8:10:b3:7d:78:b4:ce:ec:19:19:c3:73:34:b9:c7:74
+# SHA256 Fingerprint: 51:3b:2c:ec:b8:10:d4:cd:e5:dd:85:39:1a:df:c6:c2:dd:60:d8:7b:b7:36:d2:b5:21:48:4a:a4:7a:0e:be:f6
+-----BEGIN CERTIFICATE-----
+MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDEl
+MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMe
+U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoX
+DTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRy
+dXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3VyaXR5IENvbW11bmlj
+YXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANAV
+OVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGr
+zbl+dp+++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVM
+VAX3NuRFg3sUZdbcDE3R3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQ
+hNBqyjoGADdH5H5XTz+L62e4iKrFvlNVspHEfbmwhRkGeC7bYRr6hfVKkaHnFtWO
+ojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1KEOtOghY6rCcMU/Gt1SSw
+awNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8QIH4D5cs
+OPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3
+DQEBCwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpF
+coJxDjrSzG+ntKEju/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXc
+okgfGT+Ok+vx+hfuzU7jBBJV1uXk3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8
+t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6qtnRGEmyR7jTV7JqR50S+kDFy
+1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29mvVXIwAHIRc/
+SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03
+-----END CERTIFICATE-----
+
+# Issuer: CN=EC-ACC O=Agencia Catalana de Certificacio (NIF Q-0801176-I) OU=Serveis Publics de Certificacio/Vegeu https://www.catcert.net/verarrel (c)03/Jerarquia Entitats de Certificacio Catalanes
+# Subject: CN=EC-ACC O=Agencia Catalana de Certificacio (NIF Q-0801176-I) OU=Serveis Publics de Certificacio/Vegeu https://www.catcert.net/verarrel (c)03/Jerarquia Entitats de Certificacio Catalanes
+# Label: "EC-ACC"
+# Serial: -23701579247955709139626555126524820479
+# MD5 Fingerprint: eb:f5:9d:29:0d:61:f9:42:1f:7c:c2:ba:6d:e3:15:09
+# SHA1 Fingerprint: 28:90:3a:63:5b:52:80:fa:e6:77:4c:0b:6d:a7:d6:ba:a6:4a:f2:e8
+# SHA256 Fingerprint: 88:49:7f:01:60:2f:31:54:24:6a:e2:8c:4d:5a:ef:10:f1:d8:7e:bb:76:62:6f:4a:e0:b7:f9:5b:a7:96:87:99
+-----BEGIN CERTIFICATE-----
+MIIFVjCCBD6gAwIBAgIQ7is969Qh3hSoYqwE893EATANBgkqhkiG9w0BAQUFADCB
+8zELMAkGA1UEBhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2Vy
+dGlmaWNhY2lvIChOSUYgUS0wODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1
+YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYDVQQLEyxWZWdldSBodHRwczovL3d3
+dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UECxMsSmVyYXJxdWlh
+IEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMTBkVD
+LUFDQzAeFw0wMzAxMDcyMzAwMDBaFw0zMTAxMDcyMjU5NTlaMIHzMQswCQYDVQQG
+EwJFUzE7MDkGA1UEChMyQWdlbmNpYSBDYXRhbGFuYSBkZSBDZXJ0aWZpY2FjaW8g
+KE5JRiBRLTA4MDExNzYtSSkxKDAmBgNVBAsTH1NlcnZlaXMgUHVibGljcyBkZSBD
+ZXJ0aWZpY2FjaW8xNTAzBgNVBAsTLFZlZ2V1IGh0dHBzOi8vd3d3LmNhdGNlcnQu
+bmV0L3ZlcmFycmVsIChjKTAzMTUwMwYDVQQLEyxKZXJhcnF1aWEgRW50aXRhdHMg
+ZGUgQ2VydGlmaWNhY2lvIENhdGFsYW5lczEPMA0GA1UEAxMGRUMtQUNDMIIBIjAN
+BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyLHT+KXQpWIR4NA9h0X84NzJB5R
+85iKw5K4/0CQBXCHYMkAqbWUZRkiFRfCQ2xmRJoNBD45b6VLeqpjt4pEndljkYRm
+4CgPukLjbo73FCeTae6RDqNfDrHrZqJyTxIThmV6PttPB/SnCWDaOkKZx7J/sxaV
+HMf5NLWUhdWZXqBIoH7nF2W4onW4HvPlQn2v7fOKSGRdghST2MDk/7NQcvJ29rNd
+QlB50JQ+awwAvthrDk4q7D7SzIKiGGUzE3eeml0aE9jD2z3Il3rucO2n5nzbcc8t
+lGLfbdb1OL4/pYUKGbio2Al1QnDE6u/LDsg0qBIimAy4E5S2S+zw0JDnJwIDAQAB
+o4HjMIHgMB0GA1UdEQQWMBSBEmVjX2FjY0BjYXRjZXJ0Lm5ldDAPBgNVHRMBAf8E
+BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUoMOLRKo3pUW/l4Ba0fF4
+opvpXY0wfwYDVR0gBHgwdjB0BgsrBgEEAfV4AQMBCjBlMCwGCCsGAQUFBwIBFiBo
+dHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbDA1BggrBgEFBQcCAjApGidW
+ZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAwDQYJKoZIhvcN
+AQEFBQADggEBAKBIW4IB9k1IuDlVNZyAelOZ1Vr/sXE7zDkJlF7W2u++AVtd0x7Y
+/X1PzaBB4DSTv8vihpw3kpBWHNzrKQXlxJ7HNd+KDM3FIUPpqojlNcAZQmNaAl6k
+SBg6hW/cnbw/nZzBh7h6YQjpdwt/cKt63dmXLGQehb+8dJahw3oS7AwaboMMPOhy
+Rp/7SNVel+axofjk70YllJyJ22k4vuxcDlbHZVHlUIiIv0LVKz3l+bqeLrPK9HOS
+Agu+TGbrIP65y7WZf+a2E/rKS03Z7lNGBjvGTq2TWoF+bCpLagVFjPIhpDGQh2xl
+nJ2lYJU6Un/10asIbvPuW/mIPX64b24D5EI=
+-----END CERTIFICATE-----
+
+# Issuer: CN=Hellenic Academic and Research Institutions RootCA 2011 O=Hellenic Academic and Research Institutions Cert. Authority
+# Subject: CN=Hellenic Academic and Research Institutions RootCA 2011 O=Hellenic Academic and Research Institutions Cert. Authority
+# Label: "Hellenic Academic and Research Institutions RootCA 2011"
+# Serial: 0
+# MD5 Fingerprint: 73:9f:4c:4b:73:5b:79:e9:fa:ba:1c:ef:6e:cb:d5:c9
+# SHA1 Fingerprint: fe:45:65:9b:79:03:5b:98:a1:61:b5:51:2e:ac:da:58:09:48:22:4d
+# SHA256 Fingerprint: bc:10:4f:15:a4:8b:e7:09:dc:a5:42:a7:e1:d4:b9:df:6f:05:45:27:e8:02:ea:a9:2d:59:54:44:25:8a:fe:71
+-----BEGIN CERTIFICATE-----
+MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1Ix
+RDBCBgNVBAoTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1
+dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1p
+YyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIFJvb3RDQSAyMDExMB4XDTExMTIw
+NjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYTAkdSMUQwQgYDVQQK
+EztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIENl
+cnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl
+c2VhcmNoIEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEB
+BQADggEPADCCAQoCggEBAKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPz
+dYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJ
+fel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa71HFK9+WXesyHgLacEns
+bgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u8yBRQlqD
+75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSP
+FEDH3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNV
+HRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp
+5dgTBCPuQSUwRwYDVR0eBEAwPqA8MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQu
+b3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQub3JnMA0GCSqGSIb3DQEBBQUA
+A4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVtXdMiKahsog2p
+6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8
+TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7
+dIsXRSZMFpGD/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8Acys
+Nnq/onN694/BtZqhFLKPM58N7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXI
+l7WdmplNsDz4SgCbZN2fOUvRJ9e4
+-----END CERTIFICATE-----
+
+# Issuer: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967
+# Subject: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967
+# Label: "Actalis Authentication Root CA"
+# Serial: 6271844772424770508
+# MD5 Fingerprint: 69:c1:0d:4f:07:a3:1b:c3:fe:56:3d:04:bc:11:f6:a6
+# SHA1 Fingerprint: f3:73:b3:87:06:5a:28:84:8a:f2:f3:4a:ce:19:2b:dd:c7:8e:9c:ac
+# SHA256 Fingerprint: 55:92:60:84:ec:96:3a:64:b9:6e:2a:be:01:ce:0b:a8:6a:64:fb:fe:bc:c7:aa:b5:af:c1:55:b3:7f:d7:60:66
+-----BEGIN CERTIFICATE-----
+MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE
+BhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8w
+MzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290
+IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDkyMjExMjIwMlowazELMAkGA1UEBhMC
+SVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1
+ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENB
+MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNv
+UTufClrJwkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX
+4ay8IMKx4INRimlNAJZaby/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9
+KK3giq0itFZljoZUj5NDKd45RnijMCO6zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/
+gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1fYVEiVRvjRuPjPdA1Yprb
+rxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2oxgkg4YQ
+51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2F
+be8lEfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxe
+KF+w6D9Fz8+vm2/7hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4F
+v6MGn8i1zeQf1xcGDXqVdFUNaBr8EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbn
+fpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5jF66CyCU3nuDuP/jVo23Eek7
+jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLYiDrIn3hm7Ynz
+ezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt
+ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAL
+e3KHwGCmSUyIWOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70
+jsNjLiNmsGe+b7bAEzlgqqI0JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDz
+WochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKxK3JCaKygvU5a2hi/a5iB0P2avl4V
+SM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+Xlff1ANATIGk0k9j
+pwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC4yyX
+X04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+Ok
+fcvHlXHo2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7R
+K4X9p2jIugErsWx0Hbhzlefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btU
+ZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXemOR/qnuOf0GZvBeyqdn6/axag67XH/JJU
+LysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9vwGYT7JZVEc+NHt4bVaT
+LnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg==
+-----END CERTIFICATE-----
+
+# Issuer: O=Trustis Limited OU=Trustis FPS Root CA
+# Subject: O=Trustis Limited OU=Trustis FPS Root CA
+# Label: "Trustis FPS Root CA"
+# Serial: 36053640375399034304724988975563710553
+# MD5 Fingerprint: 30:c9:e7:1e:6b:e6:14:eb:65:b2:16:69:20:31:67:4d
+# SHA1 Fingerprint: 3b:c0:38:0b:33:c3:f6:a6:0c:86:15:22:93:d9:df:f5:4b:81:c0:04
+# SHA256 Fingerprint: c1:b4:82:99:ab:a5:20:8f:e9:63:0a:ce:55:ca:68:a0:3e:da:5a:51:9c:88:02:a0:d3:a6:73:be:8f:8e:55:7d
+-----BEGIN CERTIFICATE-----
+MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBF
+MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQL
+ExNUcnVzdGlzIEZQUyBSb290IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTEx
+MzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNVBAoTD1RydXN0aXMgTGltaXRlZDEc
+MBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD
+ggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQRUN+
+AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihH
+iTHcDnlkH5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjj
+vSkCqPoc4Vu5g6hBSLwacY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA
+0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zto3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlB
+OrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEAAaNTMFEwDwYDVR0TAQH/
+BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAdBgNVHQ4E
+FgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01
+GX2cGE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmW
+zaD+vkAMXBJV+JOCyinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP4
+1BIy+Q7DsdwyhEQsb8tGD+pmQQ9P8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZE
+f1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHVl/9D7S3B2l0pKoU/rGXuhg8F
+jZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYliB6XzCGcKQEN
+ZetX2fNXlrtIzYE=
+-----END CERTIFICATE-----
+
+# Issuer: CN=Buypass Class 2 Root CA O=Buypass AS-983163327
+# Subject: CN=Buypass Class 2 Root CA O=Buypass AS-983163327
+# Label: "Buypass Class 2 Root CA"
+# Serial: 2
+# MD5 Fingerprint: 46:a7:d2:fe:45:fb:64:5a:a8:59:90:9b:78:44:9b:29
+# SHA1 Fingerprint: 49:0a:75:74:de:87:0a:47:fe:58:ee:f6:c7:6b:eb:c6:0b:12:40:99
+# SHA256 Fingerprint: 9a:11:40:25:19:7c:5b:b9:5d:94:e6:3d:55:cd:43:79:08:47:b6:46:b2:3c:df:11:ad:a4:a0:0e:ff:15:fb:48
+-----BEGIN CERTIFICATE-----
+MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd
+MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg
+Q2xhc3MgMiBSb290IENBMB4XDTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1ow
+TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw
+HgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB
+BQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1g1Lr
+6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPV
+L4O2fuPn9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC91
+1K2GScuVr1QGbNgGE41b/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHx
+MlAQTn/0hpPshNOOvEu/XAFOBz3cFIqUCqTqc/sLUegTBxj6DvEr0VQVfTzh97QZ
+QmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeffawrbD02TTqigzXsu8lkB
+arcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgIzRFo1clr
+Us3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLi
+FRhnBkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRS
+P/TizPJhk9H9Z2vXUq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN
+9SG9dKpN6nIDSdvHXx1iY8f93ZHsM+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxP
+AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMmAd+BikoL1Rpzz
+uvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAU18h
+9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s
+A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3t
+OluwlN5E40EIosHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo
++fsicdl9sz1Gv7SEr5AcD48Saq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7
+KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYdDnkM/crqJIByw5c/8nerQyIKx+u2
+DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWDLfJ6v9r9jv6ly0Us
+H8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0oyLQ
+I+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK7
+5t98biGCwWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h
+3PFaTWwyI0PurKju7koSCTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPz
+Y11aWOIv4x3kqdbQCtCev9eBCfHJxyYNrJgWVqA=
+-----END CERTIFICATE-----
+
+# Issuer: CN=Buypass Class 3 Root CA O=Buypass AS-983163327
+# Subject: CN=Buypass Class 3 Root CA O=Buypass AS-983163327
+# Label: "Buypass Class 3 Root CA"
+# Serial: 2
+# MD5 Fingerprint: 3d:3b:18:9e:2c:64:5a:e8:d5:88:ce:0e:f9:37:c2:ec
+# SHA1 Fingerprint: da:fa:f7:fa:66:84:ec:06:8f:14:50:bd:c7:c2:81:a5:bc:a9:64:57
+# SHA256 Fingerprint: ed:f7:eb:bc:a2:7a:2a:38:4d:38:7b:7d:40:10:c6:66:e2:ed:b4:84:3e:4c:29:b4:ae:1d:5b:93:32:e6:b2:4d
+-----BEGIN CERTIFICATE-----
+MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd
+MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg
+Q2xhc3MgMyBSb290IENBMB4XDTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFow
+TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw
+HgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB
+BQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRHsJ8Y
+ZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3E
+N3coTRiR5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9
+tznDDgFHmV0ST9tD+leh7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX
+0DJq1l1sDPGzbjniazEuOQAnFN44wOwZZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c
+/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH2xc519woe2v1n/MuwU8X
+KhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV/afmiSTY
+zIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvS
+O1UQRwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D
+34xFMFbG02SrZvPAXpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgP
+K9Dx2hzLabjKSWJtyNBjYt1gD1iqj6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3
+AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEe4zf/lb+74suwv
+Tg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAACAj
+QTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV
+cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXS
+IGrs/CIBKM+GuIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2
+HJLw5QY33KbmkJs4j1xrG0aGQ0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsa
+O5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8ZORK15FTAaggiG6cX0S5y2CBNOxv
+033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2KSb12tjE8nVhz36u
+dmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz6MkE
+kbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg41
+3OEMXbugUZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvD
+u79leNKGef9JOxqDDPDeeOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq
+4/g7u9xN12TyUb7mqqta6THuBrxzvxNiCp/HuZc=
+-----END CERTIFICATE-----
+
+# Issuer: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center
+# Subject: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center
+# Label: "T-TeleSec GlobalRoot Class 3"
+# Serial: 1
+# MD5 Fingerprint: ca:fb:40:a8:4e:39:92:8a:1d:fe:8e:2f:c4:27:ea:ef
+# SHA1 Fingerprint: 55:a6:72:3e:cb:f2:ec:cd:c3:23:74:70:19:9d:2a:be:11:e3:81:d1
+# SHA256 Fingerprint: fd:73:da:d3:1c:64:4f:f1:b4:3b:ef:0c:cd:da:96:71:0b:9c:d9:87:5e:ca:7e:31:70:7a:f3:e9:6d:52:2b:bd
+-----BEGIN CERTIFICATE-----
+MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx
+KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd
+BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl
+YyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgxMDAxMTAyOTU2WhcNMzMxMDAxMjM1
+OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy
+aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50
+ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0G
+CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN
+8ELg63iIVl6bmlQdTQyK9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/
+RLyTPWGrTs0NvvAgJ1gORH8EGoel15YUNpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4
+hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZFiP0Zf3WHHx+xGwpzJFu5
+ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W0eDrXltM
+EnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGj
+QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1
+A/d2O2GCahKqGFPrAyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOy
+WL6ukK2YJ5f+AbGwUgC4TeQbIXQbfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ
+1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzTucpH9sry9uetuUg/vBa3wW30
+6gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7hP0HHRwA11fXT
+91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml
+e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p
+TpPDpFQUWw==
+-----END CERTIFICATE-----
+
+# Issuer: CN=EE Certification Centre Root CA O=AS Sertifitseerimiskeskus
+# Subject: CN=EE Certification Centre Root CA O=AS Sertifitseerimiskeskus
+# Label: "EE Certification Centre Root CA"
+# Serial: 112324828676200291871926431888494945866
+# MD5 Fingerprint: 43:5e:88:d4:7d:1a:4a:7e:fd:84:2e:52:eb:01:d4:6f
+# SHA1 Fingerprint: c9:a8:b9:e7:55:80:5e:58:e3:53:77:a7:25:eb:af:c3:7b:27:cc:d7
+# SHA256 Fingerprint: 3e:84:ba:43:42:90:85:16:e7:75:73:c0:99:2f:09:79:ca:08:4e:46:85:68:1f:f1:95:cc:ba:8a:22:9b:8a:76
+-----BEGIN CERTIFICATE-----
+MIIEAzCCAuugAwIBAgIQVID5oHPtPwBMyonY43HmSjANBgkqhkiG9w0BAQUFADB1
+MQswCQYDVQQGEwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1
+czEoMCYGA1UEAwwfRUUgQ2VydGlmaWNhdGlvbiBDZW50cmUgUm9vdCBDQTEYMBYG
+CSqGSIb3DQEJARYJcGtpQHNrLmVlMCIYDzIwMTAxMDMwMTAxMDMwWhgPMjAzMDEy
+MTcyMzU5NTlaMHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlBUyBTZXJ0aWZpdHNl
+ZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRyZSBS
+b290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWUwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQDIIMDs4MVLqwd4lfNE7vsLDP90jmG7sWLqI9iroWUy
+euuOF0+W2Ap7kaJjbMeMTC55v6kF/GlclY1i+blw7cNRfdCT5mzrMEvhvH2/UpvO
+bntl8jixwKIy72KyaOBhU8E2lf/slLo2rpwcpzIP5Xy0xm90/XsY6KxX7QYgSzIw
+WFv9zajmofxwvI6Sc9uXp3whrj3B9UiHbCe9nyV0gVWw93X2PaRka9ZP585ArQ/d
+MtO8ihJTmMmJ+xAdTX7Nfh9WDSFwhfYggx/2uh8Ej+p3iDXE/+pOoYtNP2MbRMNE
+1CV2yreN1x5KZmTNXMWcg+HCCIia7E6j8T4cLNlsHaFLAgMBAAGjgYowgYcwDwYD
+VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBLyWj7qVhy/
+zQas8fElyalL1BSZMEUGA1UdJQQ+MDwGCCsGAQUFBwMCBggrBgEFBQcDAQYIKwYB
+BQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYIKwYBBQUHAwkwDQYJKoZIhvcNAQEF
+BQADggEBAHv25MANqhlHt01Xo/6tu7Fq1Q+e2+RjxY6hUFaTlrg4wCQiZrxTFGGV
+v9DHKpY5P30osxBAIWrEr7BSdxjhlthWXePdNl4dp1BUoMUq5KqMlIpPnTX/dqQG
+E5Gion0ARD9V04I8GtVbvFZMIi5GQ4okQC3zErg7cBqklrkar4dBGmoYDQZPxz5u
+uSlNDUmJEYcyW+ZLBMjkXOZ0c5RdFpgTlf7727FE5TpwrDdr5rMzcijJs1eg9gIW
+iAYLtqZLICjU3j2LrTcFU3T+bsy8QxdxXvnFzBqpYe73dgzzcvRyrc9yAjYHR8/v
+GVCJYMzpJJUPwssd8m92kMfMdcGWxZ0=
+-----END CERTIFICATE-----
+
+# Issuer: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH
+# Subject: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH
+# Label: "D-TRUST Root Class 3 CA 2 2009"
+# Serial: 623603
+# MD5 Fingerprint: cd:e0:25:69:8d:47:ac:9c:89:35:90:f7:fd:51:3d:2f
+# SHA1 Fingerprint: 58:e8:ab:b0:36:15:33:fb:80:f7:9b:1b:6d:29:d3:ff:8d:5f:00:f0
+# SHA256 Fingerprint: 49:e7:a4:42:ac:f0:ea:62:87:05:00:54:b5:25:64:b6:50:e4:f4:9e:42:e3:48:d6:aa:38:e0:39:e9:57:b1:c1
+-----BEGIN CERTIFICATE-----
+MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF
+MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD
+bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha
+ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM
+HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB
+BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03
+UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42
+tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R
+ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM
+lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp
+/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G
+A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G
+A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj
+dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy
+MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl
+cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js
+L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL
+BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni
+acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0
+o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K
+zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8
+PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y
+Johw1+qRzT65ysCQblrGXnRl11z+o+I=
+-----END CERTIFICATE-----
+
+# Issuer: CN=D-TRUST Root Class 3 CA 2 EV 2009 O=D-Trust GmbH
+# Subject: CN=D-TRUST Root Class 3 CA 2 EV 2009 O=D-Trust GmbH
+# Label: "D-TRUST Root Class 3 CA 2 EV 2009"
+# Serial: 623604
+# MD5 Fingerprint: aa:c6:43:2c:5e:2d:cd:c4:34:c0:50:4f:11:02:4f:b6
+# SHA1 Fingerprint: 96:c9:1b:0b:95:b4:10:98:42:fa:d0:d8:22:79:fe:60:fa:b9:16:83
+# SHA256 Fingerprint: ee:c5:49:6b:98:8c:e9:86:25:b9:34:09:2e:ec:29:08:be:d0:b0:f3:16:c2:d4:73:0c:84:ea:f1:f3:d3:48:81
+-----BEGIN CERTIFICATE-----
+MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRF
+MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBD
+bGFzcyAzIENBIDIgRVYgMjAwOTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUw
+NDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNV
+BAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAwOTCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfSegpn
+ljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM0
+3TP1YtHhzRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6Z
+qQTMFexgaDbtCHu39b+T7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lR
+p75mpoo6Kr3HGrHhFPC+Oh25z1uxav60sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8
+HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure3511H3a6UCAwEAAaOCASQw
+ggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyvcop9Ntea
+HNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFw
+Oi8vZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xh
+c3MlMjAzJTIwQ0ElMjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1E
+RT9jZXJ0aWZpY2F0ZXJldm9jYXRpb25saXN0MEagRKBChkBodHRwOi8vd3d3LmQt
+dHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xhc3NfM19jYV8yX2V2XzIwMDku
+Y3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+PPoeUSbrh/Yp
+3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05
+nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNF
+CSuGdXzfX2lXANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7na
+xpeG0ILD5EJt/rDiZE4OJudANCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqX
+KVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVvw9y4AyHqnxbxLFS1
+-----END CERTIFICATE-----
+
+# Issuer: CN=CA Disig Root R2 O=Disig a.s.
+# Subject: CN=CA Disig Root R2 O=Disig a.s.
+# Label: "CA Disig Root R2"
+# Serial: 10572350602393338211
+# MD5 Fingerprint: 26:01:fb:d8:27:a7:17:9a:45:54:38:1a:43:01:3b:03
+# SHA1 Fingerprint: b5:61:eb:ea:a4:de:e4:25:4b:69:1a:98:a5:57:47:c2:34:c7:d9:71
+# SHA256 Fingerprint: e2:3d:4a:03:6d:7b:70:e9:f5:95:b1:42:20:79:d2:b9:1e:df:bb:1f:b6:51:a0:63:3e:aa:8a:9d:c5:f8:07:03
+-----BEGIN CERTIFICATE-----
+MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNV
+BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu
+MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQy
+MDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx
+EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjIw
+ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbCw3Oe
+NcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNH
+PWSb6WiaxswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3I
+x2ymrdMxp7zo5eFm1tL7A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbe
+QTg06ov80egEFGEtQX6sx3dOy1FU+16SGBsEWmjGycT6txOgmLcRK7fWV8x8nhfR
+yyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqVg8NTEQxzHQuyRpDRQjrO
+QG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa5Beny912
+H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJ
+QfYEkoopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUD
+i/ZnWejBBhG93c+AAk9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORs
+nLMOPReisjQS1n6yqEm70XooQL6iFh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1
+rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud
+DwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5uQu0wDQYJKoZI
+hvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM
+tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqf
+GopTpti72TVVsRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkb
+lvdhuDvEK7Z4bLQjb/D907JedR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka
++elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W81k/BfDxujRNt+3vrMNDcTa/F1bal
+TFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjxmHHEt38OFdAlab0i
+nSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01utI3
+gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18Dr
+G5gPcFw0sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3Os
+zMOl6W8KjptlwlCFtaOgUxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8x
+L4ysEr3vQCj8KWefshNPZiTEUxnpHikV7+ZtsH8tZ/3zbBt1RqPlShfppNcL
+-----END CERTIFICATE-----
+
+# Issuer: CN=ACCVRAIZ1 O=ACCV OU=PKIACCV
+# Subject: CN=ACCVRAIZ1 O=ACCV OU=PKIACCV
+# Label: "ACCVRAIZ1"
+# Serial: 6828503384748696800
+# MD5 Fingerprint: d0:a0:5a:ee:05:b6:09:94:21:a1:7d:f1:b2:29:82:02
+# SHA1 Fingerprint: 93:05:7a:88:15:c6:4f:ce:88:2f:fa:91:16:52:28:78:bc:53:64:17
+# SHA256 Fingerprint: 9a:6e:c0:12:e1:a7:da:9d:be:34:19:4d:47:8a:d7:c0:db:18:22:fb:07:1d:f1:29:81:49:6e:d1:04:38:41:13
+-----BEGIN CERTIFICATE-----
+MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UE
+AwwJQUNDVlJBSVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQsw
+CQYDVQQGEwJFUzAeFw0xMTA1MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQ
+BgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwHUEtJQUNDVjENMAsGA1UECgwEQUND
+VjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCb
+qau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gMjmoY
+HtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWo
+G2ioPej0RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpA
+lHPrzg5XPAOBOp0KoVdDaaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhr
+IA8wKFSVf+DuzgpmndFALW4ir50awQUZ0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/
+0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDGWuzndN9wrqODJerWx5eH
+k6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs78yM2x/47
+4KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMO
+m3WR5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpa
+cXpkatcnYGMN285J9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPl
+uUsXQA+xtrn13k/c4LOsOxFwYIRKQ26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYI
+KwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRwOi8vd3d3LmFjY3YuZXMvZmls
+ZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEuY3J0MB8GCCsG
+AQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2
+VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeT
+VfZW6oHlNsyMHj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIG
+CCsGAQUFBwICMIIBFB6CARAAQQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUA
+cgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBhAO0AegAgAGQAZQAgAGwAYQAgAEEA
+QwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUAYwBuAG8AbABvAGcA
+7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBjAHQA
+cgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAA
+QwBQAFMAIABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUA
+czAwBggrBgEFBQcCARYkaHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2Mu
+aHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRt
+aW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2MV9kZXIuY3JsMA4GA1Ud
+DwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZIhvcNAQEF
+BQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdp
+D70ER9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gU
+JyCpZET/LtZ1qmxNYEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+m
+AM/EKXMRNt6GGT6d7hmKG9Ww7Y49nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepD
+vV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJTS+xJlsndQAJxGJ3KQhfnlms
+tn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3sCPdK6jT2iWH
+7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h
+I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szA
+h1xA2syVP1XgNce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xF
+d3+YJ5oyXSrjhO7FmGYvliAd3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2H
+pPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3pEfbRD0tVNEYqi4Y7
+-----END CERTIFICATE-----
+
+# Issuer: CN=TWCA Global Root CA O=TAIWAN-CA OU=Root CA
+# Subject: CN=TWCA Global Root CA O=TAIWAN-CA OU=Root CA
+# Label: "TWCA Global Root CA"
+# Serial: 3262
+# MD5 Fingerprint: f9:03:7e:cf:e6:9e:3c:73:7a:2a:90:07:69:ff:2b:96
+# SHA1 Fingerprint: 9c:bb:48:53:f6:a4:f6:d3:52:a4:e8:32:52:55:60:13:f5:ad:af:65
+# SHA256 Fingerprint: 59:76:90:07:f7:68:5d:0f:cd:50:87:2f:9f:95:d5:75:5a:5b:2b:45:7d:81:f3:69:2b:61:0a:98:67:2f:0e:1b
+-----BEGIN CERTIFICATE-----
+MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcx
+EjAQBgNVBAoTCVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMT
+VFdDQSBHbG9iYWwgUm9vdCBDQTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5
+NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQKEwlUQUlXQU4tQ0ExEDAOBgNVBAsT
+B1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3QgQ0EwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2CnJfF
+10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz
+0ALfUPZVr2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfCh
+MBwqoJimFb3u/Rk28OKRQ4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbH
+zIh1HrtsBv+baz4X7GGqcXzGHaL3SekVtTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc
+46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1WKKD+u4ZqyPpcC1jcxkt2
+yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99sy2sbZCi
+laLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYP
+oA/pyJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQA
+BDzfuBSO6N+pjWxnkjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcE
+qYSjMq+u7msXi7Kx/mzhkIyIqJdIzshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm
+4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
+/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6gcFGn90xHNcgL
+1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn
+LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WF
+H6vPNOw/KP4M8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNo
+RI2T9GRwoD2dKAXDOXC4Ynsg/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+
+nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlglPx4mI88k1HtQJAH32RjJMtOcQWh
+15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryPA9gK8kxkRr05YuWW
+6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3mi4TW
+nsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5j
+wa19hAM8EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWz
+aGHQRiapIVJpLesux+t3zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmy
+KwbQBM0=
+-----END CERTIFICATE-----
+
+# Issuer: CN=TeliaSonera Root CA v1 O=TeliaSonera
+# Subject: CN=TeliaSonera Root CA v1 O=TeliaSonera
+# Label: "TeliaSonera Root CA v1"
+# Serial: 199041966741090107964904287217786801558
+# MD5 Fingerprint: 37:41:49:1b:18:56:9a:26:f5:ad:c2:66:fb:40:a5:4c
+# SHA1 Fingerprint: 43:13:bb:96:f1:d5:86:9b:c1:4e:6a:92:f6:cf:f6:34:69:87:82:37
+# SHA256 Fingerprint: dd:69:36:fe:21:f8:f0:77:c1:23:a1:a5:21:c1:22:24:f7:22:55:b7:3e:03:a7:26:06:93:e8:a2:4b:0f:a3:89
+-----BEGIN CERTIFICATE-----
+MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAw
+NzEUMBIGA1UECgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJv
+b3QgQ0EgdjEwHhcNMDcxMDE4MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYD
+VQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwWVGVsaWFTb25lcmEgUm9vdCBDQSB2
+MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+6yfwIaPzaSZVfp3F
+VRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA3GV1
+7CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+X
+Z75Ljo1kB1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+
+/jXh7VB7qTCNGdMJjmhnXb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs
+81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxHoLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkm
+dtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3F0fUTPHSiXk+TT2YqGHe
+Oh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJoWjiUIMu
+sDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4
+pgd7gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fs
+slESl1MpWtTwEhDcTwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQ
+arMCpgKIv7NHfirZ1fpoeDVNAgMBAAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYD
+VR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qWDNXr+nuqF+gTEjANBgkqhkiG
+9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNmzqjMDfz1mgbl
+dxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx
+0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1Tj
+TQpgcmLNkQfWpb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBed
+Y2gea+zDTYa4EzAvXUYNR0PVG6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7
+Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpcc41teyWRyu5FrgZLAMzTsVlQ2jqI
+OylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOTJsjrDNYmiLbAJM+7
+vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2qReW
+t88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcn
+HL/EVlP6Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVx
+SK236thZiNSQvxaz2emsWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY=
+-----END CERTIFICATE-----
+
+# Issuer: CN=E-Tugra Certification Authority O=E-Tuğra EBG Bilişim Teknolojileri ve Hizmetleri A.Ş. OU=E-Tugra Sertifikasyon Merkezi
+# Subject: CN=E-Tugra Certification Authority O=E-Tuğra EBG Bilişim Teknolojileri ve Hizmetleri A.Ş. OU=E-Tugra Sertifikasyon Merkezi
+# Label: "E-Tugra Certification Authority"
+# Serial: 7667447206703254355
+# MD5 Fingerprint: b8:a1:03:63:b0:bd:21:71:70:8a:6f:13:3a:bb:79:49
+# SHA1 Fingerprint: 51:c6:e7:08:49:06:6e:f3:92:d4:5c:a0:0d:6d:a3:62:8f:c3:52:39
+# SHA256 Fingerprint: b0:bf:d5:2b:b0:d7:d9:bd:92:bf:5d:4d:c1:3d:a2:55:c0:2c:54:2f:37:83:65:ea:89:39:11:f5:5e:55:f2:3c
+-----BEGIN CERTIFICATE-----
+MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNV
+BAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBC
+aWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNV
+BAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQDDB9FLVR1
+Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMwNTEyMDk0OFoXDTIz
+MDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+
+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhp
+em1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN
+ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5
+MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4vU/kwVRHoViVF56C/UY
+B4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vdhQd2h8y/L5VMzH2nPbxH
+D5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5KCKpbknSF
+Q9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEo
+q1+gElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3D
+k14opz8n8Y4e0ypQBaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcH
+fC425lAcP9tDJMW/hkd5s3kc91r0E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsut
+dEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gzrt48Ue7LE3wBf4QOXVGUnhMM
+ti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAqjqFGOjGY5RH8
+zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn
+rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUX
+U8u3Zg5mTPj5dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6
+Jyr+zE7S6E5UMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5
+XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAF
+Nzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAKkEh47U6YA5n+KGCR
+HTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jOXKqY
+GwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c
+77NCR807VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3
++GbHeJAAFS6LrVE1Uweoa2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WK
+vJUawSg5TB9D0pH0clmKuVb8P7Sd2nCcdlqMQ1DujjByTd//SffGqWfZbawCEeI6
+FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEVKV0jq9BgoRJP3vQXzTLl
+yb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gTDx4JnW2P
+AJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpD
+y4Q08ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8d
+NL/+I5c30jn6PQ0GC7TbO6Orb1wdtn7os4I07QZcJA==
+-----END CERTIFICATE-----
+
+# Issuer: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center
+# Subject: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center
+# Label: "T-TeleSec GlobalRoot Class 2"
+# Serial: 1
+# MD5 Fingerprint: 2b:9b:9e:e4:7b:6c:1f:00:72:1a:cc:c1:77:79:df:6a
+# SHA1 Fingerprint: 59:0d:2d:7d:88:4f:40:2e:61:7e:a5:62:32:17:65:cf:17:d8:94:e9
+# SHA256 Fingerprint: 91:e2:f5:78:8d:58:10:eb:a7:ba:58:73:7d:e1:54:8a:8e:ca:cd:01:45:98:bc:0b:14:3e:04:1b:17:05:25:52
+-----BEGIN CERTIFICATE-----
+MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx
+KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd
+BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl
+YyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgxMDAxMTA0MDE0WhcNMzMxMDAxMjM1
+OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy
+aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50
+ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0G
+CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUd
+AqSzm1nzHoqvNK38DcLZSBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiC
+FoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/FvudocP05l03Sx5iRUKrERLMjfTlH6VJi
+1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx9702cu+fjOlbpSD8DT6Iavq
+jnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGVWOHAD3bZ
+wI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGj
+QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/
+WSA2AHmgoCJrjNXyYdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhy
+NsZt+U2e+iKo4YFWz827n+qrkRk4r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPAC
+uvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNfvNoBYimipidx5joifsFvHZVw
+IEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR3p1m0IvVVGb6
+g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN
+9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP
+BSeOE6Fuwg==
+-----END CERTIFICATE-----
+
+# Issuer: CN=Atos TrustedRoot 2011 O=Atos
+# Subject: CN=Atos TrustedRoot 2011 O=Atos
+# Label: "Atos TrustedRoot 2011"
+# Serial: 6643877497813316402
+# MD5 Fingerprint: ae:b9:c4:32:4b:ac:7f:5d:66:cc:77:94:bb:2a:77:56
+# SHA1 Fingerprint: 2b:b1:f5:3e:55:0c:1d:c5:f1:d4:e6:b7:6a:46:4b:55:06:02:ac:21
+# SHA256 Fingerprint: f3:56:be:a2:44:b7:a9:1e:b3:5d:53:ca:9a:d7:86:4a:ce:01:8e:2d:35:d5:f8:f9:6d:df:68:a6:f4:1a:a4:74
+-----BEGIN CERTIFICATE-----
+MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UE
+AwwVQXRvcyBUcnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQG
+EwJERTAeFw0xMTA3MDcxNDU4MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMM
+FUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsGA1UECgwEQXRvczELMAkGA1UEBhMC
+REUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCVhTuXbyo7LjvPpvMp
+Nb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr54rM
+VD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+
+SZFhyBH+DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ
+4J7sVaE3IqKHBAUsR320HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0L
+cp2AMBYHlT8oDv3FdU9T1nSatCQujgKRz3bFmx5VdJx4IbHwLfELn8LVlhgf8FQi
+eowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7Rl+lwrrw7GWzbITAPBgNV
+HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZbNshMBgG
+A1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3
+DQEBCwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8j
+vZfza1zv7v1Apt+hk6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kP
+DpFrdRbhIfzYJsdHt6bPWHJxfrrhTZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pc
+maHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a961qn8FYiqTxlVMYVqL2Gns2D
+lmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G3mB/ufNPRJLv
+KrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed
+-----END CERTIFICATE-----
+
+# Issuer: CN=QuoVadis Root CA 1 G3 O=QuoVadis Limited
+# Subject: CN=QuoVadis Root CA 1 G3 O=QuoVadis Limited
+# Label: "QuoVadis Root CA 1 G3"
+# Serial: 687049649626669250736271037606554624078720034195
+# MD5 Fingerprint: a4:bc:5b:3f:fe:37:9a:fa:64:f0:e2:fa:05:3d:0b:ab
+# SHA1 Fingerprint: 1b:8e:ea:57:96:29:1a:c9:39:ea:b8:0a:81:1a:73:73:c0:93:79:67
+# SHA256 Fingerprint: 8a:86:6f:d1:b2:76:b5:7e:57:8e:92:1c:65:82:8a:2b:ed:58:e9:f2:f2:88:05:41:34:b7:f1:f4:bf:c9:cc:74
+-----BEGIN CERTIFICATE-----
+MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQEL
+BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc
+BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00
+MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
+aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEgRzMwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakEPBtV
+wedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWe
+rNrwU8lmPNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF341
+68Xfuw6cwI2H44g4hWf6Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh
+4Pw5qlPafX7PGglTvF0FBM+hSo+LdoINofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXp
+UhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/lg6AnhF4EwfWQvTA9xO+o
+abw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV7qJZjqlc
+3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/G
+KubX9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSt
+hfbZxbGL0eUQMk1fiyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KO
+Tk0k+17kBL5yG6YnLUlamXrXXAkgt3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOt
+zCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
+BjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZIhvcNAQELBQAD
+ggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC
+MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2
+cDMT/uFPpiN3GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUN
+qXsCHKnQO18LwIE6PWThv6ctTr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5
+YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP+V04ikkwj+3x6xn0dxoxGE1nVGwv
+b2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh3jRJjehZrJ3ydlo2
+8hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fawx/k
+NSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNj
+ZgKAvQU6O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhp
+q1467HxpvMc7hU6eFbm0FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFt
+nh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOVhMJKzRwuJIczYOXD
+-----END CERTIFICATE-----
+
+# Issuer: CN=QuoVadis Root CA 2 G3 O=QuoVadis Limited
+# Subject: CN=QuoVadis Root CA 2 G3 O=QuoVadis Limited
+# Label: "QuoVadis Root CA 2 G3"
+# Serial: 390156079458959257446133169266079962026824725800
+# MD5 Fingerprint: af:0c:86:6e:bf:40:2d:7f:0b:3e:12:50:ba:12:3d:06
+# SHA1 Fingerprint: 09:3c:61:f3:8b:8b:dc:7d:55:df:75:38:02:05:00:e1:25:f5:c8:36
+# SHA256 Fingerprint: 8f:e4:fb:0a:f9:3a:4d:0d:67:db:0b:eb:b2:3e:37:c7:1b:f3:25:dc:bc:dd:24:0e:a0:4d:af:58:b4:7e:18:40
+-----BEGIN CERTIFICATE-----
+MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQEL
+BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc
+BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00
+MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
+aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIgRzMwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFhZiFf
+qq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMW
+n4rjyduYNM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ym
+c5GQYaYDFCDy54ejiK2toIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+
+O7q414AB+6XrW7PFXmAqMaCvN+ggOp+oMiwMzAkd056OXbxMmO7FGmh77FOm6RQ1
+o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+lV0POKa2Mq1W/xPtbAd0j
+IaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZoL1NesNKq
+IcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz
+8eQQsSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43eh
+vNURG3YBZwjgQQvD6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l
+7ZizlWNof/k19N+IxWA1ksB8aRxhlRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALG
+cC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
+BjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZIhvcNAQELBQAD
+ggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66
+AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RC
+roijQ1h5fq7KpVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0Ga
+W/ZZGYjeVYg3UQt4XAoeo0L9x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4n
+lv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgzdWqTHBLmYF5vHX/JHyPLhGGfHoJE
++V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6XU/IyAgkwo1jwDQHV
+csaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+NwmNtd
+dbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNg
+KCLjsZWDzYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeM
+HVOyToV7BjjHLPj4sHKNJeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4
+WSr2Rz0ZiC3oheGe7IUIarFsNMkd7EgrO3jtZsSOeWmD3n+M
+-----END CERTIFICATE-----
+
+# Issuer: CN=QuoVadis Root CA 3 G3 O=QuoVadis Limited
+# Subject: CN=QuoVadis Root CA 3 G3 O=QuoVadis Limited
+# Label: "QuoVadis Root CA 3 G3"
+# Serial: 268090761170461462463995952157327242137089239581
+# MD5 Fingerprint: df:7d:b9:ad:54:6f:68:a1:df:89:57:03:97:43:b0:d7
+# SHA1 Fingerprint: 48:12:bd:92:3c:a8:c4:39:06:e7:30:6d:27:96:e6:a4:cf:22:2e:7d
+# SHA256 Fingerprint: 88:ef:81:de:20:2e:b0:18:45:2e:43:f8:64:72:5c:ea:5f:bd:1f:c2:d9:d2:05:73:07:09:c5:d8:b8:69:0f:46
+-----BEGIN CERTIFICATE-----
+MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQEL
+BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc
+BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00
+MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
+aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMgRzMwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286IxSR
+/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNu
+FoM7pmRLMon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXR
+U7Ox7sWTaYI+FrUoRqHe6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+c
+ra1AdHkrAj80//ogaX3T7mH1urPnMNA3I4ZyYUUpSFlob3emLoG+B01vr87ERROR
+FHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3UVDmrJqMz6nWB2i3ND0/k
+A9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f75li59wzw
+eyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634Ryl
+sSqiMd5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBp
+VzgeAVuNVejH38DMdyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0Q
+A4XN8f+MFrXBsj6IbGB/kE+V9/YtrQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+
+ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
+BjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZIhvcNAQELBQAD
+ggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px
+KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnI
+FUBhynLWcKzSt/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5Wvv
+oxXqA/4Ti2Tk08HS6IT7SdEQTXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFg
+u/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9DuDcpmvJRPpq3t/O5jrFc/ZSXPsoaP
+0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGibIh6BJpsQBJFxwAYf
+3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmDhPbl
+8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+
+DhcI00iX0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HN
+PlopNLk9hM6xZdRZkZFWdSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/
+ywaZWWDYWGWVjUTR939+J399roD1B0y2PpxxVJkES/1Y+Zj0
+-----END CERTIFICATE-----
+
+# Issuer: CN=DigiCert Assured ID Root G2 O=DigiCert Inc OU=www.digicert.com
+# Subject: CN=DigiCert Assured ID Root G2 O=DigiCert Inc OU=www.digicert.com
+# Label: "DigiCert Assured ID Root G2"
+# Serial: 15385348160840213938643033620894905419
+# MD5 Fingerprint: 92:38:b9:f8:63:24:82:65:2c:57:33:e6:fe:81:8f:9d
+# SHA1 Fingerprint: a1:4b:48:d9:43:ee:0a:0e:40:90:4f:3c:e0:a4:c0:91:93:51:5d:3f
+# SHA256 Fingerprint: 7d:05:eb:b6:82:33:9f:8c:94:51:ee:09:4e:eb:fe:fa:79:53:a1:14:ed:b2:f4:49:49:45:2f:ab:7d:2f:c1:85
+-----BEGIN CERTIFICATE-----
+MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv
+b3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQG
+EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl
+cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwggEi
+MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSA
+n61UQbVH35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4Htecc
+biJVMWWXvdMX0h5i89vqbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9Hp
+EgjAALAcKxHad3A2m67OeYfcgnDmCXRwVWmvo2ifv922ebPynXApVfSr/5Vh88lA
+bx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OPYLfykqGxvYmJHzDNw6Yu
+YjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+RnlTGNAgMB
+AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQW
+BBTOw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPI
+QW5pJ6d1Ee88hjZv0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I
+0jJmwYrA8y8678Dj1JGG0VDjA9tzd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4Gni
+lmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9
+B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv
+ON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo
+IhNzbM8m9Yop5w==
+-----END CERTIFICATE-----
+
+# Issuer: CN=DigiCert Assured ID Root G3 O=DigiCert Inc OU=www.digicert.com
+# Subject: CN=DigiCert Assured ID Root G3 O=DigiCert Inc OU=www.digicert.com
+# Label: "DigiCert Assured ID Root G3"
+# Serial: 15459312981008553731928384953135426796
+# MD5 Fingerprint: 7c:7f:65:31:0c:81:df:8d:ba:3e:99:e2:5c:ad:6e:fb
+# SHA1 Fingerprint: f5:17:a2:4f:9a:48:c6:c9:f8:a2:00:26:9f:dc:0f:48:2c:ab:30:89
+# SHA256 Fingerprint: 7e:37:cb:8b:4c:47:09:0c:ab:36:55:1b:a6:f4:5d:b8:40:68:0f:ba:16:6a:95:2d:b1:00:71:7f:43:05:3f:c2
+-----BEGIN CERTIFICATE-----
+MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw
+CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
+ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg
+RzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJV
+UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu
+Y29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQBgcq
+hkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJf
+Zn4f5dwbRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17Q
+RSAPWXYQ1qAk8C3eNvJsKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/
+BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD
+AwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY
+JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv
+6pZjamVFkpUBtA==
+-----END CERTIFICATE-----
+
+# Issuer: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com
+# Subject: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com
+# Label: "DigiCert Global Root G2"
+# Serial: 4293743540046975378534879503202253541
+# MD5 Fingerprint: e4:a6:8a:c8:54:ac:52:42:46:0a:fd:72:48:1b:2a:44
+# SHA1 Fingerprint: df:3c:24:f9:bf:d6:66:76:1b:26:80:73:fe:06:d1:cc:8d:4f:82:a4
+# SHA256 Fingerprint: cb:3c:cb:b7:60:31:e5:e0:13:8f:8d:d3:9a:23:f9:de:47:ff:c3:5e:43:c1:14:4c:ea:27:d4:6a:5a:b1:cb:5f
+-----BEGIN CERTIFICATE-----
+MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH
+MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT
+MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
+b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI
+2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx
+1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ
+q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz
+tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ
+vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP
+BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV
+5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY
+1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4
+NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG
+Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91
+8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe
+pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl
+MrY=
+-----END CERTIFICATE-----
+
+# Issuer: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com
+# Subject: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com
+# Label: "DigiCert Global Root G3"
+# Serial: 7089244469030293291760083333884364146
+# MD5 Fingerprint: f5:5d:a4:50:a5:fb:28:7e:1e:0f:0d:cc:96:57:56:ca
+# SHA1 Fingerprint: 7e:04:de:89:6a:3e:66:6d:00:e6:87:d3:3f:fa:d9:3b:e8:3d:34:9e
+# SHA256 Fingerprint: 31:ad:66:48:f8:10:41:38:c7:38:f3:9e:a4:32:01:33:39:3e:3a:18:cc:02:29:6e:f9:7c:2a:c9:ef:67:31:d0
+-----BEGIN CERTIFICATE-----
+MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw
+CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
+ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe
+Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw
+EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x
+IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF
+K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG
+fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO
+Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd
+BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx
+AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/
+oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8
+sycX
+-----END CERTIFICATE-----
+
+# Issuer: CN=DigiCert Trusted Root G4 O=DigiCert Inc OU=www.digicert.com
+# Subject: CN=DigiCert Trusted Root G4 O=DigiCert Inc OU=www.digicert.com
+# Label: "DigiCert Trusted Root G4"
+# Serial: 7451500558977370777930084869016614236
+# MD5 Fingerprint: 78:f2:fc:aa:60:1f:2f:b4:eb:c9:37:ba:53:2e:75:49
+# SHA1 Fingerprint: dd:fb:16:cd:49:31:c9:73:a2:03:7d:3f:c8:3a:4d:7d:77:5d:05:e4
+# SHA256 Fingerprint: 55:2f:7b:dc:f1:a7:af:9e:6c:e6:72:01:7f:4f:12:ab:f7:72:40:c7:8e:76:1a:c2:03:d1:d9:d2:0a:c8:99:88
+-----BEGIN CERTIFICATE-----
+MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg
+RzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJV
+UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu
+Y29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3y
+ithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1If
+xp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDV
+ySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiO
+DCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQ
+jdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/
+CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCi
+EhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADM
+fRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QY
+uKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXK
+chYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t
+9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
+hjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD
+ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2
+SV1EY+CtnJYYZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd
++SeuMIW59mdNOj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWc
+fFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqa
+sjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9N
+cCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N
+0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie
+4u1Ki7wb/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mI
+r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1
+/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm
+gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+
+-----END CERTIFICATE-----
+
+# Issuer: CN=COMODO RSA Certification Authority O=COMODO CA Limited
+# Subject: CN=COMODO RSA Certification Authority O=COMODO CA Limited
+# Label: "COMODO RSA Certification Authority"
+# Serial: 101909084537582093308941363524873193117
+# MD5 Fingerprint: 1b:31:b0:71:40:36:cc:14:36:91:ad:c4:3e:fd:ec:18
+# SHA1 Fingerprint: af:e5:d2:44:a8:d1:19:42:30:ff:47:9f:e2:f8:97:bb:cd:7a:8c:b4
+# SHA256 Fingerprint: 52:f0:e1:c4:e5:8e:c6:29:29:1b:60:31:7f:07:46:71:b8:5d:7e:a8:0d:5b:07:27:34:63:53:4b:32:b4:02:34
+-----BEGIN CERTIFICATE-----
+MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB
+hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
+A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV
+BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMTE5
+MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT
+EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR
+Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNh
+dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR
+6FSS0gpWsawNJN3Fz0RndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8X
+pz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC
+9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+5eNu/Nio5JIk2kNrYrhV
+/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pGx8cgoLEf
+Zd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z
++pUX2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7w
+qP/0uK3pN/u6uPQLOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZah
+SL0896+1DSJMwBGB7FY79tOi4lu3sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVIC
+u9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+CGCe01a60y1Dma/RMhnEw6abf
+Fobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5WdYgGq/yapiq
+crxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E
+FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB
+/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvl
+wFTPoCWOAvn9sKIN9SCYPBMtrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM
+4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV
+2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSgtZx8jb8uk2Intzna
+FxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwWsRqZ
+CuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiK
+boHGhfKppC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmcke
+jkk9u+UJueBPSZI9FoJAzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yL
+S0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb
+QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl
+0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB
+NVOFBkpdn627G190
+-----END CERTIFICATE-----
+
+# Issuer: CN=USERTrust RSA Certification Authority O=The USERTRUST Network
+# Subject: CN=USERTrust RSA Certification Authority O=The USERTRUST Network
+# Label: "USERTrust RSA Certification Authority"
+# Serial: 2645093764781058787591871645665788717
+# MD5 Fingerprint: 1b:fe:69:d1:91:b7:19:33:a3:72:a8:0f:e1:55:e5:b5
+# SHA1 Fingerprint: 2b:8f:1b:57:33:0d:bb:a2:d0:7a:6c:51:f7:0e:e9:0d:da:b9:ad:8e
+# SHA256 Fingerprint: e7:93:c9:b0:2f:d8:aa:13:e2:1c:31:22:8a:cc:b0:81:19:64:3b:74:9c:89:89:64:b1:74:6d:46:c3:d4:cb:d2
+-----BEGIN CERTIFICATE-----
+MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB
+iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl
+cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV
+BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw
+MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV
+BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU
+aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy
+dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
+AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B
+3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY
+tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/
+Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2
+VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT
+79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6
+c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT
+Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l
+c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee
+UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE
+Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd
+BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G
+A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF
+Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO
+VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3
+ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs
+8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR
+iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze
+Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ
+XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/
+qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB
+VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB
+L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG
+jjxDah2nGN59PRbxYvnKkKj9
+-----END CERTIFICATE-----
+
+# Issuer: CN=USERTrust ECC Certification Authority O=The USERTRUST Network
+# Subject: CN=USERTrust ECC Certification Authority O=The USERTRUST Network
+# Label: "USERTrust ECC Certification Authority"
+# Serial: 123013823720199481456569720443997572134
+# MD5 Fingerprint: fa:68:bc:d9:b5:7f:ad:fd:c9:1d:06:83:28:cc:24:c1
+# SHA1 Fingerprint: d1:cb:ca:5d:b2:d5:2a:7f:69:3b:67:4d:e5:f0:5a:1d:0c:95:7d:f0
+# SHA256 Fingerprint: 4f:f4:60:d5:4b:9c:86:da:bf:bc:fc:57:12:e0:40:0d:2b:ed:3f:bc:4d:4f:bd:aa:86:e0:6a:dc:d2:a9:ad:7a
+-----BEGIN CERTIFICATE-----
+MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDEL
+MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl
+eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT
+JVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMjAx
+MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT
+Ck5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUg
+VVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlm
+aWNhdGlvbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqflo
+I+d61SRvU8Za2EurxtW20eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinng
+o4N+LZfQYcTxmdwlkWOrfzCjtHDix6EznPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0G
+A1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNVHQ8BAf8EBAMCAQYwDwYD
+VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBBHU6+4WMB
+zzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbW
+RNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg=
+-----END CERTIFICATE-----
+
+# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4
+# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4
+# Label: "GlobalSign ECC Root CA - R4"
+# Serial: 14367148294922964480859022125800977897474
+# MD5 Fingerprint: 20:f0:27:68:d1:7e:a0:9d:0e:e6:2a:ca:df:5c:89:8e
+# SHA1 Fingerprint: 69:69:56:2e:40:80:f4:24:a1:e7:19:9f:14:ba:f3:ee:58:ab:6a:bb
+# SHA256 Fingerprint: be:c9:49:11:c2:95:56:76:db:6c:0a:55:09:86:d7:6e:3b:a0:05:66:7c:44:2c:97:62:b4:fb:b7:73:de:22:8c
+-----BEGIN CERTIFICATE-----
+MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEk
+MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpH
+bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX
+DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD
+QSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu
+MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprlOQcJ
+FspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAw
+DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61F
+uOJAf/sKbvu+M8k8o4TVMAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGX
+kPoUVy0D7O48027KqGx2vKLeuwIgJ6iFJzWbVsaj8kfSt24bAgAXqmemFZHe+pTs
+ewv4n4Q=
+-----END CERTIFICATE-----
+
+# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R5
+# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R5
+# Label: "GlobalSign ECC Root CA - R5"
+# Serial: 32785792099990507226680698011560947931244
+# MD5 Fingerprint: 9f:ad:3b:1c:02:1e:8a:ba:17:74:38:81:0c:a2:bc:08
+# SHA1 Fingerprint: 1f:24:c6:30:cd:a4:18:ef:20:69:ff:ad:4f:dd:5f:46:3a:1b:69:aa
+# SHA256 Fingerprint: 17:9f:bc:14:8a:3d:d0:0f:d2:4e:a1:34:58:cc:43:bf:a7:f5:9c:81:82:d7:83:a5:13:f6:eb:ec:10:0c:89:24
+-----BEGIN CERTIFICATE-----
+MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEk
+MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpH
+bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX
+DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD
+QSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu
+MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6SFkc
+8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8ke
+hOvRnkmSh5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD
+VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYI
+KoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg
+515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7yFz9SO8NdCKoCOJuxUnO
+xwy8p2Fp8fc74SrL+SvzZpA3
+-----END CERTIFICATE-----
+
+# Issuer: CN=Staat der Nederlanden Root CA - G3 O=Staat der Nederlanden
+# Subject: CN=Staat der Nederlanden Root CA - G3 O=Staat der Nederlanden
+# Label: "Staat der Nederlanden Root CA - G3"
+# Serial: 10003001
+# MD5 Fingerprint: 0b:46:67:07:db:10:2f:19:8c:35:50:60:d1:0b:f4:37
+# SHA1 Fingerprint: d8:eb:6b:41:51:92:59:e0:f3:e7:85:00:c0:3d:b6:88:97:c9:ee:fc
+# SHA256 Fingerprint: 3c:4f:b0:b9:5a:b8:b3:00:32:f4:32:b8:6f:53:5f:e1:72:c1:85:d0:fd:39:86:58:37:cf:36:18:7f:a6:f4:28
+-----BEGIN CERTIFICATE-----
+MIIFdDCCA1ygAwIBAgIEAJiiOTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO
+TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh
+dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEczMB4XDTEzMTExNDExMjg0MloX
+DTI4MTExMzIzMDAwMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl
+ciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv
+b3QgQ0EgLSBHMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL4yolQP
+cPssXFnrbMSkUeiFKrPMSjTysF/zDsccPVMeiAho2G89rcKezIJnByeHaHE6n3WW
+IkYFsO2tx1ueKt6c/DrGlaf1F2cY5y9JCAxcz+bMNO14+1Cx3Gsy8KL+tjzk7FqX
+xz8ecAgwoNzFs21v0IJyEavSgWhZghe3eJJg+szeP4TrjTgzkApyI/o1zCZxMdFy
+KJLZWyNtZrVtB0LrpjPOktvA9mxjeM3KTj215VKb8b475lRgsGYeCasH/lSJEULR
+9yS6YHgamPfJEf0WwTUaVHXvQ9Plrk7O53vDxk5hUUurmkVLoR9BvUhTFXFkC4az
+5S6+zqQbwSmEorXLCCN2QyIkHxcE1G6cxvx/K2Ya7Irl1s9N9WMJtxU51nus6+N8
+6U78dULI7ViVDAZCopz35HCz33JvWjdAidiFpNfxC95DGdRKWCyMijmev4SH8RY7
+Ngzp07TKbBlBUgmhHbBqv4LvcFEhMtwFdozL92TkA1CvjJFnq8Xy7ljY3r735zHP
+bMk7ccHViLVlvMDoFxcHErVc0qsgk7TmgoNwNsXNo42ti+yjwUOH5kPiNL6VizXt
+BznaqB16nzaeErAMZRKQFWDZJkBE41ZgpRDUajz9QdwOWke275dhdU/Z/seyHdTt
+XUmzqWrLZoQT1Vyg3N9udwbRcXXIV2+vD3dbAgMBAAGjQjBAMA8GA1UdEwEB/wQF
+MAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRUrfrHkleuyjWcLhL75Lpd
+INyUVzANBgkqhkiG9w0BAQsFAAOCAgEAMJmdBTLIXg47mAE6iqTnB/d6+Oea31BD
+U5cqPco8R5gu4RV78ZLzYdqQJRZlwJ9UXQ4DO1t3ApyEtg2YXzTdO2PCwyiBwpwp
+LiniyMMB8jPqKqrMCQj3ZWfGzd/TtiunvczRDnBfuCPRy5FOCvTIeuXZYzbB1N/8
+Ipf3YF3qKS9Ysr1YvY2WTxB1v0h7PVGHoTx0IsL8B3+A3MSs/mrBcDCw6Y5p4ixp
+gZQJut3+TcCDjJRYwEYgr5wfAvg1VUkvRtTA8KCWAg8zxXHzniN9lLf9OtMJgwYh
+/WA9rjLA0u6NpvDntIJ8CsxwyXmA+P5M9zWEGYox+wrZ13+b8KKaa8MFSu1BYBQw
+0aoRQm7TIwIEC8Zl3d1Sd9qBa7Ko+gE4uZbqKmxnl4mUnrzhVNXkanjvSr0rmj1A
+fsbAddJu+2gw7OyLnflJNZoaLNmzlTnVHpL3prllL+U9bTpITAjc5CgSKL59NVzq
+4BZ+Extq1z7XnvwtdbLBFNUjA9tbbws+eC8N3jONFrdI54OagQ97wUNNVQQXOEpR
+1VmiiXTTn74eS9fGbbeIJG9gkaSChVtWQbzQRKtqE77RLFi3EjNYsjdj3BP1lB0/
+QFH1T/U67cjF68IeHRaVesd+QnGTbksVtzDfqu1XhUisHWrdOWnk4Xl4vs4Fv6EM
+94B7IWcnMFk=
+-----END CERTIFICATE-----
+
+# Issuer: CN=Staat der Nederlanden EV Root CA O=Staat der Nederlanden
+# Subject: CN=Staat der Nederlanden EV Root CA O=Staat der Nederlanden
+# Label: "Staat der Nederlanden EV Root CA"
+# Serial: 10000013
+# MD5 Fingerprint: fc:06:af:7b:e8:1a:f1:9a:b4:e8:d2:70:1f:c0:f5:ba
+# SHA1 Fingerprint: 76:e2:7e:c1:4f:db:82:c1:c0:a6:75:b5:05:be:3d:29:b4:ed:db:bb
+# SHA256 Fingerprint: 4d:24:91:41:4c:fe:95:67:46:ec:4c:ef:a6:cf:6f:72:e2:8a:13:29:43:2f:9d:8a:90:7a:c4:cb:5d:ad:c1:5a
+-----BEGIN CERTIFICATE-----
+MIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJO
+TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFh
+dCBkZXIgTmVkZXJsYW5kZW4gRVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0y
+MjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIg
+TmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRlcmxhbmRlbiBFViBS
+b290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkkSzrS
+M4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nC
+UiY4iKTWO0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3d
+Z//BYY1jTw+bbRcwJu+r0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46p
+rfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8Kj6GyzyDOvnJDdrFmeK8eEEzduG/L13l
+pJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gVXJrm0w912fxBmJc+qiXb
+j5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr08C+eKxC
+KFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS
+/ZbV0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0X
+cgOPvZuM5l5Tnrmd74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH
+1vI4gnPah1vlPNOePqc7nvQDs/nxfRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrP
+px9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB
+/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwaivsnuL8wbqg7
+MA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI
+eK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u
+2dfOWBfoqSmuc0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHS
+v4ilf0X8rLiltTMMgsT7B/Zq5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTC
+wPTxGfARKbalGAKb12NMcIxHowNDXLldRqANb/9Zjr7dn3LDWyvfjFvO5QxGbJKy
+CqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tNf1zuacpzEPuKqf2e
+vTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi5Dp6
+Z2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIa
+Gl6I6lD4WeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeL
+eG9QgkRQP2YGiqtDhFZKDyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8
+FVdMpEbB4IMeDExNH08GGeL5qPQ6gqGyeUN51q1veieQA6TqJIc/2b3Z6fJfUEkc
+7uzXLg==
+-----END CERTIFICATE-----
+
+# Issuer: CN=IdenTrust Commercial Root CA 1 O=IdenTrust
+# Subject: CN=IdenTrust Commercial Root CA 1 O=IdenTrust
+# Label: "IdenTrust Commercial Root CA 1"
+# Serial: 13298821034946342390520003877796839426
+# MD5 Fingerprint: b3:3e:77:73:75:ee:a0:d3:e3:7e:49:63:49:59:bb:c7
+# SHA1 Fingerprint: df:71:7e:aa:4a:d9:4e:c9:55:84:99:60:2d:48:de:5f:bc:f0:3a:25
+# SHA256 Fingerprint: 5d:56:49:9b:e4:d2:e0:8b:cf:ca:d0:8a:3e:38:72:3d:50:50:3b:de:70:69:48:e4:2f:55:60:30:19:e5:28:ae
+-----BEGIN CERTIFICATE-----
+MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBK
+MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVu
+VHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQw
+MTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScw
+JQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ldhNlT
+3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU
++ehcCuz/mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gp
+S0l4PJNgiCL8mdo2yMKi1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1
+bVoE/c40yiTcdCMbXTMTEl3EASX2MN0CXZ/g1Ue9tOsbobtJSdifWwLziuQkkORi
+T0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl3ZBWzvurpWCdxJ35UrCL
+vYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzyNeVJSQjK
+Vsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZK
+dHzVWYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHT
+c+XvvqDtMwt0viAgxGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hv
+l7yTmvmcEpB4eoCHFddydJxVdHixuuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5N
+iGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
+/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZIhvcNAQELBQAD
+ggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH
+6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwt
+LRvM7Kqas6pgghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93
+nAbowacYXVKV7cndJZ5t+qntozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3
++wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmVYjzlVYA211QC//G5Xc7UI2/YRYRK
+W2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUXfeu+h1sXIFRRk0pT
+AwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/rokTLq
+l1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG
+4iZZRHUe2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZ
+mUlO+KWA2yUPHGNiiskzZ2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A
+7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7RcGzM7vRX+Bi6hG6H
+-----END CERTIFICATE-----
+
+# Issuer: CN=IdenTrust Public Sector Root CA 1 O=IdenTrust
+# Subject: CN=IdenTrust Public Sector Root CA 1 O=IdenTrust
+# Label: "IdenTrust Public Sector Root CA 1"
+# Serial: 13298821034946342390521976156843933698
+# MD5 Fingerprint: 37:06:a5:b0:fc:89:9d:ba:f4:6b:8c:1a:64:cd:d5:ba
+# SHA1 Fingerprint: ba:29:41:60:77:98:3f:f4:f3:ef:f2:31:05:3b:2e:ea:6d:4d:45:fd
+# SHA256 Fingerprint: 30:d0:89:5a:9a:44:8a:26:20:91:63:55:22:d1:f5:20:10:b5:86:7a:ca:e1:2c:78:ef:95:8f:d4:f4:38:9f:2f
+-----BEGIN CERTIFICATE-----
+MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBN
+MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVu
+VHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcN
+MzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0
+MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwggIi
+MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTyP4o7
+ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGy
+RBb06tD6Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlS
+bdsHyo+1W/CD80/HLaXIrcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF
+/YTLNiCBWS2ab21ISGHKTN9T0a9SvESfqy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R
+3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoSmJxZZoY+rfGwyj4GD3vw
+EUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFnol57plzy
+9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9V
+GxyhLrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ
+2fjXctscvG29ZV/viDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsV
+WaFHVCkugyhfHMKiq3IXAAaOReyL4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gD
+W/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/
+BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMwDQYJKoZIhvcN
+AQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj
+t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHV
+DRDtfULAj+7AmgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9
+TaDKQGXSc3z1i9kKlT/YPyNtGtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8G
+lwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFtm6/n6J91eEyrRjuazr8FGF1NFTwW
+mhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMxNRF4eKLg6TCMf4Df
+WN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4Mhn5
++bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJ
+tshquDDIajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhA
+GaQdp/lLQzfcaFpPz+vCZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv
+8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ3Wl9af0AVqW3rLatt8o+Ae+c
+-----END CERTIFICATE-----
+
+# Issuer: CN=Entrust Root Certification Authority - G2 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2009 Entrust, Inc. - for authorized use only
+# Subject: CN=Entrust Root Certification Authority - G2 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2009 Entrust, Inc. - for authorized use only
+# Label: "Entrust Root Certification Authority - G2"
+# Serial: 1246989352
+# MD5 Fingerprint: 4b:e2:c9:91:96:65:0c:f4:0e:5a:93:92:a0:0a:fe:b2
+# SHA1 Fingerprint: 8c:f4:27:fd:79:0c:3a:d1:66:06:8d:e8:1e:57:ef:bb:93:22:72:d4
+# SHA256 Fingerprint: 43:df:57:74:b0:3e:7f:ef:5f:e4:0d:93:1a:7b:ed:f1:bb:2e:6b:42:73:8c:4e:6d:38:41:10:3d:3a:a7:f3:39
+-----BEGIN CERTIFICATE-----
+MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC
+VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50
+cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs
+IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz
+dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMDkwNzA3MTcy
+NTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu
+dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt
+dGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0
+aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmlj
+YXRpb24gQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
+AoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP/vaCeb9zYQYKpSfYs1/T
+RU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXzHHfV1IWN
+cCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hW
+wcKUs/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1
+U1+cPvQXLOZprE4yTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0
+jaWvYkxN4FisZDQSA/i2jZRjJKRxAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAP
+BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ60B7vfec7aVHUbI2fkBJmqzAN
+BgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5ZiXMRrEPR9RP/
+jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ
+Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v
+1fN2D807iDginWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4R
+nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH
+VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g==
+-----END CERTIFICATE-----
+
+# Issuer: CN=Entrust Root Certification Authority - EC1 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2012 Entrust, Inc. - for authorized use only
+# Subject: CN=Entrust Root Certification Authority - EC1 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2012 Entrust, Inc. - for authorized use only
+# Label: "Entrust Root Certification Authority - EC1"
+# Serial: 51543124481930649114116133369
+# MD5 Fingerprint: b6:7e:1d:f0:58:c5:49:6c:24:3b:3d:ed:98:18:ed:bc
+# SHA1 Fingerprint: 20:d8:06:40:df:9b:25:f5:12:25:3a:11:ea:f7:59:8a:eb:14:b5:47
+# SHA256 Fingerprint: 02:ed:0e:b2:8c:14:da:45:16:5c:56:67:91:70:0d:64:51:d7:fb:56:f0:b2:ab:1d:3b:8e:b0:70:e5:6e:df:f5
+-----BEGIN CERTIFICATE-----
+MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkG
+A1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3
+d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVu
+dHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEzMDEGA1UEAxMq
+RW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRUMxMB4XDTEy
+MTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYwFAYD
+VQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0
+L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0g
+Zm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBD
+ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEVDMTB2MBAGByqGSM49AgEGBSuBBAAi
+A2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHyAsWfoPZb1YsGGYZPUxBt
+ByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef9eNi1KlH
+Bz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O
+BBYEFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVC
+R98crlOZF7ZvHH3hvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nX
+hTcGtXsI/esni0qU+eH6p44mCOh8kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G
+-----END CERTIFICATE-----
+
+# Issuer: CN=CFCA EV ROOT O=China Financial Certification Authority
+# Subject: CN=CFCA EV ROOT O=China Financial Certification Authority
+# Label: "CFCA EV ROOT"
+# Serial: 407555286
+# MD5 Fingerprint: 74:e1:b6:ed:26:7a:7a:44:30:33:94:ab:7b:27:81:30
+# SHA1 Fingerprint: e2:b8:29:4b:55:84:ab:6b:58:c2:90:46:6c:ac:3f:b8:39:8f:84:83
+# SHA256 Fingerprint: 5c:c3:d7:8e:4e:1d:5e:45:54:7a:04:e6:87:3e:64:f9:0c:f9:53:6d:1c:cc:2e:f8:00:f3:55:c4:c5:fd:70:fd
+-----BEGIN CERTIFICATE-----
+MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJD
+TjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9y
+aXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkx
+MjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5j
+aWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJP
+T1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnVBU03
+sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpL
+TIpTUnrD7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5
+/ZOkVIBMUtRSqy5J35DNuF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp
+7hZZLDRJGqgG16iI0gNyejLi6mhNbiyWZXvKWfry4t3uMCz7zEasxGPrb382KzRz
+EpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7xzbh72fROdOXW3NiGUgt
+hxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9fpy25IGvP
+a931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqot
+aK8KgWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNg
+TnYGmE69g60dWIolhdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfV
+PKPtl8MeNPo4+QgO48BdK4PRVmrJtqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hv
+cWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAfBgNVHSMEGDAWgBTj/i39KNAL
+tbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAd
+BgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB
+ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObT
+ej/tUxPQ4i9qecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdL
+jOztUmCypAbqTuv0axn96/Ua4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBS
+ESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sGE5uPhnEFtC+NiWYzKXZUmhH4J/qy
+P5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfXBDrDMlI1Dlb4pd19
+xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjnaH9d
+Ci77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN
+5mydLIhyPDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe
+/v5WOaHIz16eGWRGENoXkbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+Z
+AAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3CekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ
+5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su
+-----END CERTIFICATE-----
+
+# Issuer: CN=TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H5 O=TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş.
+# Subject: CN=TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H5 O=TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş.
+# Label: "TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H5"
+# Serial: 156233699172481
+# MD5 Fingerprint: da:70:8e:f0:22:df:93:26:f6:5f:9f:d3:15:06:52:4e
+# SHA1 Fingerprint: c4:18:f6:4d:46:d1:df:00:3d:27:30:13:72:43:a9:12:11:c6:75:fb
+# SHA256 Fingerprint: 49:35:1b:90:34:44:c1:85:cc:dc:5c:69:3d:24:d8:55:5c:b2:08:d6:a8:14:13:07:69:9f:4a:f0:63:19:9d:78
+-----BEGIN CERTIFICATE-----
+MIIEJzCCAw+gAwIBAgIHAI4X/iQggTANBgkqhkiG9w0BAQsFADCBsTELMAkGA1UE
+BhMCVFIxDzANBgNVBAcMBkFua2FyYTFNMEsGA1UECgxEVMOcUktUUlVTVCBCaWxn
+aSDEsGxldGnFn2ltIHZlIEJpbGnFn2ltIEfDvHZlbmxpxJ9pIEhpem1ldGxlcmkg
+QS7Fni4xQjBABgNVBAMMOVTDnFJLVFJVU1QgRWxla3Ryb25payBTZXJ0aWZpa2Eg
+SGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSBINTAeFw0xMzA0MzAwODA3MDFaFw0yMzA0
+MjgwODA3MDFaMIGxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMU0wSwYD
+VQQKDERUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8
+dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLjFCMEAGA1UEAww5VMOcUktUUlVTVCBF
+bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIEg1MIIB
+IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApCUZ4WWe60ghUEoI5RHwWrom
+/4NZzkQqL/7hzmAD/I0Dpe3/a6i6zDQGn1k19uwsu537jVJp45wnEFPzpALFp/kR
+Gml1bsMdi9GYjZOHp3GXDSHHmflS0yxjXVW86B8BSLlg/kJK9siArs1mep5Fimh3
+4khon6La8eHBEJ/rPCmBp+EyCNSgBbGM+42WAA4+Jd9ThiI7/PS98wl+d+yG6w8z
+5UNP9FR1bSmZLmZaQ9/LXMrI5Tjxfjs1nQ/0xVqhzPMggCTTV+wVunUlm+hkS7M0
+hO8EuPbJbKoCPrZV4jI3X/xml1/N1p7HIL9Nxqw/dV8c7TKcfGkAaZHjIxhT6QID
+AQABo0IwQDAdBgNVHQ4EFgQUVpkHHtOsDGlktAxQR95DLL4gwPswDgYDVR0PAQH/
+BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAJ5FdnsX
+SDLyOIspve6WSk6BGLFRRyDN0GSxDsnZAdkJzsiZ3GglE9Rc8qPoBP5yCccLqh0l
+VX6Wmle3usURehnmp349hQ71+S4pL+f5bFgWV1Al9j4uPqrtd3GqqpmWRgqujuwq
+URawXs3qZwQcWDD1YIq9pr1N5Za0/EKJAWv2cMhQOQwt1WbZyNKzMrcbGW3LM/nf
+peYVhDfwwvJllpKQd/Ct9JDpEXjXk4nAPQu6KfTomZ1yju2dL+6SfaHx/126M2CF
+Yv4HAqGEVka+lgqaE9chTLd8B59OTj+RdPsnnRHM3eaxynFNExc5JsUpISuTKWqW
++qtB4Uu2NQvAmxU=
+-----END CERTIFICATE-----
+
+# Issuer: CN=Certinomis - Root CA O=Certinomis OU=0002 433998903
+# Subject: CN=Certinomis - Root CA O=Certinomis OU=0002 433998903
+# Label: "Certinomis - Root CA"
+# Serial: 1
+# MD5 Fingerprint: 14:0a:fd:8d:a8:28:b5:38:69:db:56:7e:61:22:03:3f
+# SHA1 Fingerprint: 9d:70:bb:01:a5:a4:a0:18:11:2e:f7:1c:01:b9:32:c5:34:e7:88:a8
+# SHA256 Fingerprint: 2a:99:f5:bc:11:74:b7:3c:bb:1d:62:08:84:e0:1c:34:e5:1c:cb:39:78:da:12:5f:0e:33:26:88:83:bf:41:58
+-----BEGIN CERTIFICATE-----
+MIIFkjCCA3qgAwIBAgIBATANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJGUjET
+MBEGA1UEChMKQ2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxHTAb
+BgNVBAMTFENlcnRpbm9taXMgLSBSb290IENBMB4XDTEzMTAyMTA5MTcxOFoXDTMz
+MTAyMTA5MTcxOFowWjELMAkGA1UEBhMCRlIxEzARBgNVBAoTCkNlcnRpbm9taXMx
+FzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMR0wGwYDVQQDExRDZXJ0aW5vbWlzIC0g
+Um9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANTMCQosP5L2
+fxSeC5yaah1AMGT9qt8OHgZbn1CF6s2Nq0Nn3rD6foCWnoR4kkjW4znuzuRZWJfl
+LieY6pOod5tK8O90gC3rMB+12ceAnGInkYjwSond3IjmFPnVAy//ldu9n+ws+hQV
+WZUKxkd8aRi5pwP5ynapz8dvtF4F/u7BUrJ1Mofs7SlmO/NKFoL21prbcpjp3vDF
+TKWrteoB4owuZH9kb/2jJZOLyKIOSY008B/sWEUuNKqEUL3nskoTuLAPrjhdsKkb
+5nPJWqHZZkCqqU2mNAKthH6yI8H7KsZn9DS2sJVqM09xRLWtwHkziOC/7aOgFLSc
+CbAK42C++PhmiM1b8XcF4LVzbsF9Ri6OSyemzTUK/eVNfaoqoynHWmgE6OXWk6Ri
+wsXm9E/G+Z8ajYJJGYrKWUM66A0ywfRMEwNvbqY/kXPLynNvEiCL7sCCeN5LLsJJ
+wx3tFvYk9CcbXFcx3FXuqB5vbKziRcxXV4p1VxngtViZSTYxPDMBbRZKzbgqg4SG
+m/lg0h9tkQPTYKbVPZrdd5A9NaSfD171UkRpucC63M9933zZxKyGIjK8e2uR73r4
+F2iw4lNVYC2vPsKD2NkJK/DAZNuHi5HMkesE/Xa0lZrmFAYb1TQdvtj/dBxThZng
+WVJKYe2InmtJiUZ+IFrZ50rlau7SZRFDAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIB
+BjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTvkUz1pcMw6C8I6tNxIqSSaHh0
+2TAfBgNVHSMEGDAWgBTvkUz1pcMw6C8I6tNxIqSSaHh02TANBgkqhkiG9w0BAQsF
+AAOCAgEAfj1U2iJdGlg+O1QnurrMyOMaauo++RLrVl89UM7g6kgmJs95Vn6RHJk/
+0KGRHCwPT5iVWVO90CLYiF2cN/z7ZMF4jIuaYAnq1fohX9B0ZedQxb8uuQsLrbWw
+F6YSjNRieOpWauwK0kDDPAUwPk2Ut59KA9N9J0u2/kTO+hkzGm2kQtHdzMjI1xZS
+g081lLMSVX3l4kLr5JyTCcBMWwerx20RoFAXlCOotQqSD7J6wWAsOMwaplv/8gzj
+qh8c3LigkyfeY+N/IZ865Z764BNqdeuWXGKRlI5nU7aJ+BIJy29SWwNyhlCVCNSN
+h4YVH5Uk2KRvms6knZtt0rJ2BobGVgjF6wnaNsIbW0G+YSrjcOa4pvi2WsS9Iff/
+ql+hbHY5ZtbqTFXhADObE5hjyW/QASAJN1LnDE8+zbz1X5YnpyACleAu6AdBBR8V
+btaw5BngDwKTACdyxYvRVB9dSsNAl35VpnzBMwQUAR1JIGkLGZOdblgi90AMRgwj
+Y/M50n92Uaf0yKHxDHYiI0ZSKS3io0EHVmmY0gUJvGnHWmHNj4FgFU2A3ZDifcRQ
+8ow7bkrHxuaAKzyBvBGAFhAn1/DNP3nMcyrDflOR1m749fPH0FFNjkulW+YZFzvW
+gQncItzujrnEj1PhZ7szuIgVRs/taTX/dQ1G885x4cVrhkIGuUE=
+-----END CERTIFICATE-----
+
+# Issuer: CN=OISTE WISeKey Global Root GB CA O=WISeKey OU=OISTE Foundation Endorsed
+# Subject: CN=OISTE WISeKey Global Root GB CA O=WISeKey OU=OISTE Foundation Endorsed
+# Label: "OISTE WISeKey Global Root GB CA"
+# Serial: 157768595616588414422159278966750757568
+# MD5 Fingerprint: a4:eb:b9:61:28:2e:b7:2f:98:b0:35:26:90:99:51:1d
+# SHA1 Fingerprint: 0f:f9:40:76:18:d3:d7:6a:4b:98:f0:a8:35:9e:0c:fd:27:ac:cc:ed
+# SHA256 Fingerprint: 6b:9c:08:e8:6e:b0:f7:67:cf:ad:65:cd:98:b6:21:49:e5:49:4a:67:f5:84:5e:7b:d1:ed:01:9f:27:b8:6b:d6
+-----BEGIN CERTIFICATE-----
+MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBt
+MQswCQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUg
+Rm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9i
+YWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAwMzJaFw0zOTEyMDExNTEwMzFaMG0x
+CzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBG
+b3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2Jh
+bCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3
+HEokKtaXscriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGx
+WuR51jIjK+FTzJlFXHtPrby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX
+1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNk
+u7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4oQnc/nSMbsrY9gBQHTC5P
+99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvgGUpuuy9r
+M2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw
+AwEB/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUB
+BAMCAQAwDQYJKoZIhvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrgh
+cViXfa43FK8+5/ea4n32cZiZBKpDdHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5
+gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0VQreUGdNZtGn//3ZwLWoo4rO
+ZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEuiHZeeevJuQHHf
+aPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic
+Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM=
+-----END CERTIFICATE-----
+
+# Issuer: CN=SZAFIR ROOT CA2 O=Krajowa Izba Rozliczeniowa S.A.
+# Subject: CN=SZAFIR ROOT CA2 O=Krajowa Izba Rozliczeniowa S.A.
+# Label: "SZAFIR ROOT CA2"
+# Serial: 357043034767186914217277344587386743377558296292
+# MD5 Fingerprint: 11:64:c1:89:b0:24:b1:8c:b1:07:7e:89:9e:51:9e:99
+# SHA1 Fingerprint: e2:52:fa:95:3f:ed:db:24:60:bd:6e:28:f3:9c:cc:cf:5e:b3:3f:de
+# SHA256 Fingerprint: a1:33:9d:33:28:1a:0b:56:e5:57:d3:d3:2b:1c:e7:f9:36:7e:b0:94:bd:5f:a7:2a:7e:50:04:c8:de:d7:ca:fe
+-----BEGIN CERTIFICATE-----
+MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQEL
+BQAwUTELMAkGA1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6
+ZW5pb3dhIFMuQS4xGDAWBgNVBAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkw
+NzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9L
+cmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYDVQQDDA9TWkFGSVIg
+Uk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5QqEvN
+QLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT
+3PSQ1hNKDJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw
+3gAeqDRHu5rr/gsUvTaE2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr6
+3fE9biCloBK0TXC5ztdyO4mTp4CEHCdJckm1/zuVnsHMyAHs6A6KCpbns6aH5db5
+BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwiieDhZNRnvDF5YTy7ykHN
+XGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD
+AgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsF
+AAOCAQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw
+8PRBEew/R40/cof5O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOG
+nXkZ7/e7DDWQw4rtTw/1zBLZpD67oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCP
+oky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul4+vJhaAlIDf7js4MNIThPIGy
+d05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6+/NNIxuZMzSg
+LvWpCz/UXeHPhJ/iGcJfitYgHuNztw==
+-----END CERTIFICATE-----
+
+# Issuer: CN=Certum Trusted Network CA 2 O=Unizeto Technologies S.A. OU=Certum Certification Authority
+# Subject: CN=Certum Trusted Network CA 2 O=Unizeto Technologies S.A. OU=Certum Certification Authority
+# Label: "Certum Trusted Network CA 2"
+# Serial: 44979900017204383099463764357512596969
+# MD5 Fingerprint: 6d:46:9e:d9:25:6d:08:23:5b:5e:74:7d:1e:27:db:f2
+# SHA1 Fingerprint: d3:dd:48:3e:2b:bf:4c:05:e8:af:10:f5:fa:76:26:cf:d3:dc:30:92
+# SHA256 Fingerprint: b6:76:f2:ed:da:e8:77:5c:d3:6c:b0:f6:3c:d1:d4:60:39:61:f4:9e:62:65:ba:01:3a:2f:03:07:b6:d0:b8:04
+-----BEGIN CERTIFICATE-----
+MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCB
+gDELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMu
+QS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIG
+A1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQSAyMCIYDzIwMTExMDA2MDgz
+OTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQTDEiMCAGA1UEChMZ
+VW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRp
+ZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3
+b3JrIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWA
+DGSdhhuWZGc/IjoedQF97/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn
+0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+oCgCXhVqqndwpyeI1B+twTUrWwbNWuKFB
+OJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40bRr5HMNUuctHFY9rnY3lE
+fktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2puTRZCr+E
+Sv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1m
+o130GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02i
+sx7QBlrd9pPPV3WZ9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOW
+OZV7bIBaTxNyxtd9KXpEulKkKtVBRgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgez
+Tv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pyehizKV/Ma5ciSixqClnrDvFAS
+adgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vMBhBgu4M1t15n
+3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD
+AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMC
+AQYwDQYJKoZIhvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQ
+F/xlhMcQSZDe28cmk4gmb3DWAl45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTf
+CVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuAL55MYIR4PSFk1vtBHxgP58l1cb29
+XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMoclm2q8KMZiYcdywm
+djWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tMpkT/
+WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jb
+AoJnwTnbw3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksq
+P/ujmv5zMnHCnsZy4YpoJ/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Ko
+b7a6bINDd82Kkhehnlt4Fj1F4jNy3eFmypnTycUm/Q1oBEauttmbjL4ZvrHG8hnj
+XALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLXis7VmFxWlgPF7ncGNf/P
+5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7zAYspsbi
+DrW5viSP
+-----END CERTIFICATE-----
+
+# Issuer: CN=Hellenic Academic and Research Institutions RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority
+# Subject: CN=Hellenic Academic and Research Institutions RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority
+# Label: "Hellenic Academic and Research Institutions RootCA 2015"
+# Serial: 0
+# MD5 Fingerprint: ca:ff:e2:db:03:d9:cb:4b:e9:0f:ad:84:fd:7b:18:ce
+# SHA1 Fingerprint: 01:0c:06:95:a6:98:19:14:ff:bf:5f:c6:b0:b6:95:ea:29:e9:12:a6
+# SHA256 Fingerprint: a0:40:92:9a:02:ce:53:b4:ac:f4:f2:ff:c6:98:1c:e4:49:6f:75:5e:6d:45:fe:0b:2a:69:2b:cd:52:52:3f:36
+-----BEGIN CERTIFICATE-----
+MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1Ix
+DzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5k
+IFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMT
+N0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9v
+dENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAxMTIxWjCBpjELMAkG
+A1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNh
+ZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkx
+QDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1
+dGlvbnMgUm9vdENBIDIwMTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
+AQDC+Kk/G4n8PDwEXT2QNrCROnk8ZlrvbTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA
+4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+ehiGsxr/CL0BgzuNtFajT0
+AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+6PAQZe10
+4S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06C
+ojXdFPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV
+9Cz82XBST3i4vTwri5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrD
+gfgXy5I2XdGj2HUb4Ysn6npIQf1FGQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6
+Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2fu/Z8VFRfS0myGlZYeCsargq
+NhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9muiNX6hME6wGko
+LfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc
+Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNV
+HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVd
+ctA4GGqd83EkVAswDQYJKoZIhvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0I
+XtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+D1hYc2Ryx+hFjtyp8iY/xnmMsVMI
+M4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrMd/K4kPFox/la/vot
+9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+yd+2V
+Z5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/ea
+j8GsGsVn82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnh
+X9izjFk0WaSrT2y7HxjbdavYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQ
+l033DlZdwJVqwjbDG2jJ9SrcR5q+ss7FJej6A7na+RZukYT1HCjI/CbM1xyQVqdf
+bzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVtJ94Cj8rDtSvK6evIIVM4
+pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGaJI7ZjnHK
+e7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0
+vm9qp/UsQu0yrbYhnr68
+-----END CERTIFICATE-----
+
+# Issuer: CN=Hellenic Academic and Research Institutions ECC RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority
+# Subject: CN=Hellenic Academic and Research Institutions ECC RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority
+# Label: "Hellenic Academic and Research Institutions ECC RootCA 2015"
+# Serial: 0
+# MD5 Fingerprint: 81:e5:b4:17:eb:c2:f5:e1:4b:0d:41:7b:49:92:fe:ef
+# SHA1 Fingerprint: 9f:f1:71:8d:92:d5:9a:f3:7d:74:97:b4:bc:6f:84:68:0b:ba:b6:66
+# SHA256 Fingerprint: 44:b5:45:aa:8a:25:e6:5a:73:ca:15:dc:27:fc:36:d2:4c:1c:b9:95:3a:06:65:39:b1:15:82:dc:48:7b:48:33
+-----BEGIN CERTIFICATE-----
+MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzAN
+BgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl
+c2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hl
+bGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgRUNDIFJv
+b3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEwMzcxMlowgaoxCzAJ
+BgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmljIEFj
+YWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5
+MUQwQgYDVQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0
+dXRpb25zIEVDQyBSb290Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKg
+QehLgoRc4vgxEZmGZE4JJS+dQS8KrjVPdJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJa
+jq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoKVlp8aQuqgAkkbH7BRqNC
+MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFLQi
+C4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaep
+lSTAGiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7Sof
+TUwJCA3sS61kFyjndc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR
+-----END CERTIFICATE-----
+
+# Issuer: CN=Certplus Root CA G1 O=Certplus
+# Subject: CN=Certplus Root CA G1 O=Certplus
+# Label: "Certplus Root CA G1"
+# Serial: 1491911565779898356709731176965615564637713
+# MD5 Fingerprint: 7f:09:9c:f7:d9:b9:5c:69:69:56:d5:37:3e:14:0d:42
+# SHA1 Fingerprint: 22:fd:d0:b7:fd:a2:4e:0d:ac:49:2c:a0:ac:a6:7b:6a:1f:e3:f7:66
+# SHA256 Fingerprint: 15:2a:40:2b:fc:df:2c:d5:48:05:4d:22:75:b3:9c:7f:ca:3e:c0:97:80:78:b0:f0:ea:76:e5:61:a6:c7:43:3e
+-----BEGIN CERTIFICATE-----
+MIIFazCCA1OgAwIBAgISESBVg+QtPlRWhS2DN7cs3EYRMA0GCSqGSIb3DQEBDQUA
+MD4xCzAJBgNVBAYTAkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2Vy
+dHBsdXMgUm9vdCBDQSBHMTAeFw0xNDA1MjYwMDAwMDBaFw0zODAxMTUwMDAwMDBa
+MD4xCzAJBgNVBAYTAkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2Vy
+dHBsdXMgUm9vdCBDQSBHMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
+ANpQh7bauKk+nWT6VjOaVj0W5QOVsjQcmm1iBdTYj+eJZJ+622SLZOZ5KmHNr49a
+iZFluVj8tANfkT8tEBXgfs+8/H9DZ6itXjYj2JizTfNDnjl8KvzsiNWI7nC9hRYt
+6kuJPKNxQv4c/dMcLRC4hlTqQ7jbxofaqK6AJc96Jh2qkbBIb6613p7Y1/oA/caP
+0FG7Yn2ksYyy/yARujVjBYZHYEMzkPZHogNPlk2dT8Hq6pyi/jQu3rfKG3akt62f
+6ajUeD94/vI4CTYd0hYCyOwqaK/1jpTvLRN6HkJKHRUxrgwEV/xhc/MxVoYxgKDE
+EW4wduOU8F8ExKyHcomYxZ3MVwia9Az8fXoFOvpHgDm2z4QTd28n6v+WZxcIbekN
+1iNQMLAVdBM+5S//Ds3EC0pd8NgAM0lm66EYfFkuPSi5YXHLtaW6uOrc4nBvCGrc
+h2c0798wct3zyT8j/zXhviEpIDCB5BmlIOklynMxdCm+4kLV87ImZsdo/Rmz5yCT
+mehd4F6H50boJZwKKSTUzViGUkAksnsPmBIgJPaQbEfIDbsYIC7Z/fyL8inqh3SV
+4EJQeIQEQWGw9CEjjy3LKCHyamz0GqbFFLQ3ZU+V/YDI+HLlJWvEYLF7bY5KinPO
+WftwenMGE9nTdDckQQoRb5fc5+R+ob0V8rqHDz1oihYHAgMBAAGjYzBhMA4GA1Ud
+DwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSowcCbkahDFXxd
+Bie0KlHYlwuBsTAfBgNVHSMEGDAWgBSowcCbkahDFXxdBie0KlHYlwuBsTANBgkq
+hkiG9w0BAQ0FAAOCAgEAnFZvAX7RvUz1isbwJh/k4DgYzDLDKTudQSk0YcbX8ACh
+66Ryj5QXvBMsdbRX7gp8CXrc1cqh0DQT+Hern+X+2B50ioUHj3/MeXrKls3N/U/7
+/SMNkPX0XtPGYX2eEeAC7gkE2Qfdpoq3DIMku4NQkv5gdRE+2J2winq14J2by5BS
+S7CTKtQ+FjPlnsZlFT5kOwQ/2wyPX1wdaR+v8+khjPPvl/aatxm2hHSco1S1cE5j
+2FddUyGbQJJD+tZ3VTNPZNX70Cxqjm0lpu+F6ALEUz65noe8zDUa3qHpimOHZR4R
+Kttjd5cUvpoUmRGywO6wT/gUITJDT5+rosuoD6o7BlXGEilXCNQ314cnrUlZp5Gr
+RHpejXDbl85IULFzk/bwg2D5zfHhMf1bfHEhYxQUqq/F3pN+aLHsIqKqkHWetUNy
+6mSjhEv9DKgma3GX7lZjZuhCVPnHHd/Qj1vfyDBviP4NxDMcU6ij/UgQ8uQKTuEV
+V/xuZDDCVRHc6qnNSlSsKWNEz0pAoNZoWRsz+e86i9sgktxChL8Bq4fA1SCC28a5
+g4VCXA9DO2pJNdWY9BW/+mGBDAkgGNLQFwzLSABQ6XaCjGTXOqAHVcweMcDvOrRl
+++O/QmueD6i9a5jc2NvLi6Td11n0bt3+qsOR0C5CB8AMTVPNJLFMWx5R9N/pkvo=
+-----END CERTIFICATE-----
+
+# Issuer: CN=Certplus Root CA G2 O=Certplus
+# Subject: CN=Certplus Root CA G2 O=Certplus
+# Label: "Certplus Root CA G2"
+# Serial: 1492087096131536844209563509228951875861589
+# MD5 Fingerprint: a7:ee:c4:78:2d:1b:ee:2d:b9:29:ce:d6:a7:96:32:31
+# SHA1 Fingerprint: 4f:65:8e:1f:e9:06:d8:28:02:e9:54:47:41:c9:54:25:5d:69:cc:1a
+# SHA256 Fingerprint: 6c:c0:50:41:e6:44:5e:74:69:6c:4c:fb:c9:f8:0f:54:3b:7e:ab:bb:44:b4:ce:6f:78:7c:6a:99:71:c4:2f:17
+-----BEGIN CERTIFICATE-----
+MIICHDCCAaKgAwIBAgISESDZkc6uo+jF5//pAq/Pc7xVMAoGCCqGSM49BAMDMD4x
+CzAJBgNVBAYTAkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBs
+dXMgUm9vdCBDQSBHMjAeFw0xNDA1MjYwMDAwMDBaFw0zODAxMTUwMDAwMDBaMD4x
+CzAJBgNVBAYTAkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBs
+dXMgUm9vdCBDQSBHMjB2MBAGByqGSM49AgEGBSuBBAAiA2IABM0PW1aC3/BFGtat
+93nwHcmsltaeTpwftEIRyoa/bfuFo8XlGVzX7qY/aWfYeOKmycTbLXku54uNAm8x
+Ik0G42ByRZ0OQneezs/lf4WbGOT8zC5y0xaTTsqZY1yhBSpsBqNjMGEwDgYDVR0P
+AQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNqDYwJ5jtpMxjwj
+FNiPwyCrKGBZMB8GA1UdIwQYMBaAFNqDYwJ5jtpMxjwjFNiPwyCrKGBZMAoGCCqG
+SM49BAMDA2gAMGUCMHD+sAvZ94OX7PNVHdTcswYO/jOYnYs5kGuUIe22113WTNch
+p+e/IQ8rzfcq3IUHnQIxAIYUFuXcsGXCwI4Un78kFmjlvPl5adytRSv3tjFzzAal
+U5ORGpOucGpnutee5WEaXw==
+-----END CERTIFICATE-----
+
+# Issuer: CN=OpenTrust Root CA G1 O=OpenTrust
+# Subject: CN=OpenTrust Root CA G1 O=OpenTrust
+# Label: "OpenTrust Root CA G1"
+# Serial: 1492036577811947013770400127034825178844775
+# MD5 Fingerprint: 76:00:cc:81:29:cd:55:5e:88:6a:7a:2e:f7:4d:39:da
+# SHA1 Fingerprint: 79:91:e8:34:f7:e2:ee:dd:08:95:01:52:e9:55:2d:14:e9:58:d5:7e
+# SHA256 Fingerprint: 56:c7:71:28:d9:8c:18:d9:1b:4c:fd:ff:bc:25:ee:91:03:d4:75:8e:a2:ab:ad:82:6a:90:f3:45:7d:46:0e:b4
+-----BEGIN CERTIFICATE-----
+MIIFbzCCA1egAwIBAgISESCzkFU5fX82bWTCp59rY45nMA0GCSqGSIb3DQEBCwUA
+MEAxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9w
+ZW5UcnVzdCBSb290IENBIEcxMB4XDTE0MDUyNjA4NDU1MFoXDTM4MDExNTAwMDAw
+MFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCU9wZW5UcnVzdDEdMBsGA1UEAwwU
+T3BlblRydXN0IFJvb3QgQ0EgRzEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
+AoICAQD4eUbalsUwXopxAy1wpLuwxQjczeY1wICkES3d5oeuXT2R0odsN7faYp6b
+wiTXj/HbpqbfRm9RpnHLPhsxZ2L3EVs0J9V5ToybWL0iEA1cJwzdMOWo010hOHQX
+/uMftk87ay3bfWAfjH1MBcLrARYVmBSO0ZB3Ij/swjm4eTrwSSTilZHcYTSSjFR0
+77F9jAHiOH3BX2pfJLKOYheteSCtqx234LSWSE9mQxAGFiQD4eCcjsZGT44ameGP
+uY4zbGneWK2gDqdkVBFpRGZPTBKnjix9xNRbxQA0MMHZmf4yzgeEtE7NCv82TWLx
+p2NX5Ntqp66/K7nJ5rInieV+mhxNaMbBGN4zK1FGSxyO9z0M+Yo0FMT7MzUj8czx
+Kselu7Cizv5Ta01BG2Yospb6p64KTrk5M0ScdMGTHPjgniQlQ/GbI4Kq3ywgsNw2
+TgOzfALU5nsaqocTvz6hdLubDuHAk5/XpGbKuxs74zD0M1mKB3IDVedzagMxbm+W
+G+Oin6+Sx+31QrclTDsTBM8clq8cIqPQqwWyTBIjUtz9GVsnnB47ev1CI9sjgBPw
+vFEVVJSmdz7QdFG9URQIOTfLHzSpMJ1ShC5VkLG631UAC9hWLbFJSXKAqWLXwPYY
+EQRVzXR7z2FwefR7LFxckvzluFqrTJOVoSfupb7PcSNCupt2LQIDAQABo2MwYTAO
+BgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUl0YhVyE1
+2jZVx/PxN3DlCPaTKbYwHwYDVR0jBBgwFoAUl0YhVyE12jZVx/PxN3DlCPaTKbYw
+DQYJKoZIhvcNAQELBQADggIBAB3dAmB84DWn5ph76kTOZ0BP8pNuZtQ5iSas000E
+PLuHIT839HEl2ku6q5aCgZG27dmxpGWX4m9kWaSW7mDKHyP7Rbr/jyTwyqkxf3kf
+gLMtMrpkZ2CvuVnN35pJ06iCsfmYlIrM4LvgBBuZYLFGZdwIorJGnkSI6pN+VxbS
+FXJfLkur1J1juONI5f6ELlgKn0Md/rcYkoZDSw6cMoYsYPXpSOqV7XAp8dUv/TW0
+V8/bhUiZucJvbI/NeJWsZCj9VrDDb8O+WVLhX4SPgPL0DTatdrOjteFkdjpY3H1P
+XlZs5VVZV6Xf8YpmMIzUUmI4d7S+KNfKNsSbBfD4Fdvb8e80nR14SohWZ25g/4/I
+i+GOvUKpMwpZQhISKvqxnUOOBZuZ2mKtVzazHbYNeS2WuOvyDEsMpZTGMKcmGS3t
+TAZQMPH9WD25SxdfGbRqhFS0OE85og2WaMMolP3tLR9Ka0OWLpABEPs4poEL0L91
+09S5zvE/bw4cHjdx5RiHdRk/ULlepEU0rbDK5uUTdg8xFKmOLZTW1YVNcxVPS/Ky
+Pu1svf0OnWZzsD2097+o4BGkxK51CUpjAEggpsadCwmKtODmzj7HPiY46SvepghJ
+AwSQiumPv+i2tCqjI40cHLI5kqiPAlxAOXXUc0ECd97N4EOH1uS6SsNsEn/+KuYj
+1oxx
+-----END CERTIFICATE-----
+
+# Issuer: CN=OpenTrust Root CA G2 O=OpenTrust
+# Subject: CN=OpenTrust Root CA G2 O=OpenTrust
+# Label: "OpenTrust Root CA G2"
+# Serial: 1492012448042702096986875987676935573415441
+# MD5 Fingerprint: 57:24:b6:59:24:6b:ae:c8:fe:1c:0c:20:f2:c0:4e:eb
+# SHA1 Fingerprint: 79:5f:88:60:c5:ab:7c:3d:92:e6:cb:f4:8d:e1:45:cd:11:ef:60:0b
+# SHA256 Fingerprint: 27:99:58:29:fe:6a:75:15:c1:bf:e8:48:f9:c4:76:1d:b1:6c:22:59:29:25:7b:f4:0d:08:94:f2:9e:a8:ba:f2
+-----BEGIN CERTIFICATE-----
+MIIFbzCCA1egAwIBAgISESChaRu/vbm9UpaPI+hIvyYRMA0GCSqGSIb3DQEBDQUA
+MEAxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9w
+ZW5UcnVzdCBSb290IENBIEcyMB4XDTE0MDUyNjAwMDAwMFoXDTM4MDExNTAwMDAw
+MFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCU9wZW5UcnVzdDEdMBsGA1UEAwwU
+T3BlblRydXN0IFJvb3QgQ0EgRzIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
+AoICAQDMtlelM5QQgTJT32F+D3Y5z1zCU3UdSXqWON2ic2rxb95eolq5cSG+Ntmh
+/LzubKh8NBpxGuga2F8ORAbtp+Dz0mEL4DKiltE48MLaARf85KxP6O6JHnSrT78e
+CbY2albz4e6WiWYkBuTNQjpK3eCasMSCRbP+yatcfD7J6xcvDH1urqWPyKwlCm/6
+1UWY0jUJ9gNDlP7ZvyCVeYCYitmJNbtRG6Q3ffyZO6v/v6wNj0OxmXsWEH4db0fE
+FY8ElggGQgT4hNYdvJGmQr5J1WqIP7wtUdGejeBSzFfdNTVY27SPJIjki9/ca1TS
+gSuyzpJLHB9G+h3Ykst2Z7UJmQnlrBcUVXDGPKBWCgOz3GIZ38i1MH/1PCZ1Eb3X
+G7OHngevZXHloM8apwkQHZOJZlvoPGIytbU6bumFAYueQ4xncyhZW+vj3CzMpSZy
+YhK05pyDRPZRpOLAeiRXyg6lPzq1O4vldu5w5pLeFlwoW5cZJ5L+epJUzpM5ChaH
+vGOz9bGTXOBut9Dq+WIyiET7vycotjCVXRIouZW+j1MY5aIYFuJWpLIsEPUdN6b4
+t/bQWVyJ98LVtZR00dX+G7bw5tYee9I8y6jj9RjzIR9u701oBnstXW5DiabA+aC/
+gh7PU3+06yzbXfZqfUAkBXKJOAGTy3HCOV0GEfZvePg3DTmEJwIDAQABo2MwYTAO
+BgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUajn6QiL3
+5okATV59M4PLuG53hq8wHwYDVR0jBBgwFoAUajn6QiL35okATV59M4PLuG53hq8w
+DQYJKoZIhvcNAQENBQADggIBAJjLq0A85TMCl38th6aP1F5Kr7ge57tx+4BkJamz
+Gj5oXScmp7oq4fBXgwpkTx4idBvpkF/wrM//T2h6OKQQbA2xx6R3gBi2oihEdqc0
+nXGEL8pZ0keImUEiyTCYYW49qKgFbdEfwFFEVn8nNQLdXpgKQuswv42hm1GqO+qT
+RmTFAHneIWv2V6CG1wZy7HBGS4tz3aAhdT7cHcCP009zHIXZ/n9iyJVvttN7jLpT
+wm+bREx50B1ws9efAvSyB7DH5fitIw6mVskpEndI2S9G/Tvw/HRwkqWOOAgfZDC2
+t0v7NqwQjqBSM2OdAzVWxWm9xiNaJ5T2pBL4LTM8oValX9YZ6e18CL13zSdkzJTa
+TkZQh+D5wVOAHrut+0dSixv9ovneDiK3PTNZbNTe9ZUGMg1RGUFcPk8G97krgCf2
+o6p6fAbhQ8MTOWIaNr3gKC6UAuQpLmBVrkA9sHSSXvAgZJY/X0VdiLWK2gKgW0VU
+3jg9CcCoSmVGFvyqv1ROTVu+OEO3KMqLM6oaJbolXCkvW0pujOotnCr2BXbgd5eA
+iN1nE28daCSLT7d0geX0YJ96Vdc+N9oWaz53rK4YcJUIeSkDiv7BO7M/Gg+kO14f
+WKGVyasvc0rQLW6aWQ9VGHgtPFGml4vmu7JwqkwR3v98KzfUetF3NI/n+UL3PIEM
+S1IK
+-----END CERTIFICATE-----
+
+# Issuer: CN=OpenTrust Root CA G3 O=OpenTrust
+# Subject: CN=OpenTrust Root CA G3 O=OpenTrust
+# Label: "OpenTrust Root CA G3"
+# Serial: 1492104908271485653071219941864171170455615
+# MD5 Fingerprint: 21:37:b4:17:16:92:7b:67:46:70:a9:96:d7:a8:13:24
+# SHA1 Fingerprint: 6e:26:64:f3:56:bf:34:55:bf:d1:93:3f:7c:01:de:d8:13:da:8a:a6
+# SHA256 Fingerprint: b7:c3:62:31:70:6e:81:07:8c:36:7c:b8:96:19:8f:1e:32:08:dd:92:69:49:dd:8f:57:09:a4:10:f7:5b:62:92
+-----BEGIN CERTIFICATE-----
+MIICITCCAaagAwIBAgISESDm+Ez8JLC+BUCs2oMbNGA/MAoGCCqGSM49BAMDMEAx
+CzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9wZW5U
+cnVzdCBSb290IENBIEczMB4XDTE0MDUyNjAwMDAwMFoXDTM4MDExNTAwMDAwMFow
+QDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCU9wZW5UcnVzdDEdMBsGA1UEAwwUT3Bl
+blRydXN0IFJvb3QgQ0EgRzMwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARK7liuTcpm
+3gY6oxH84Bjwbhy6LTAMidnW7ptzg6kjFYwvWYpa3RTqnVkrQ7cG7DK2uu5Bta1d
+oYXM6h0UZqNnfkbilPPntlahFVmhTzeXuSIevRHr9LIfXsMUmuXZl5mjYzBhMA4G
+A1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRHd8MUi2I5
+DMlv4VBN0BBY3JWIbTAfBgNVHSMEGDAWgBRHd8MUi2I5DMlv4VBN0BBY3JWIbTAK
+BggqhkjOPQQDAwNpADBmAjEAj6jcnboMBBf6Fek9LykBl7+BFjNAk2z8+e2AcG+q
+j9uEwov1NcoG3GRvaBbhj5G5AjEA2Euly8LQCGzpGPta3U1fJAuwACEl74+nBCZx
+4nxp5V2a+EEfOzmTk51V6s2N8fvB
+-----END CERTIFICATE-----
+
+# Issuer: CN=ISRG Root X1 O=Internet Security Research Group
+# Subject: CN=ISRG Root X1 O=Internet Security Research Group
+# Label: "ISRG Root X1"
+# Serial: 172886928669790476064670243504169061120
+# MD5 Fingerprint: 0c:d2:f9:e0:da:17:73:e9:ed:86:4d:a5:e3:70:e7:4e
+# SHA1 Fingerprint: ca:bd:2a:79:a1:07:6a:31:f2:1d:25:36:35:cb:03:9d:43:29:a5:e8
+# SHA256 Fingerprint: 96:bc:ec:06:26:49:76:f3:74:60:77:9a:cf:28:c5:a7:cf:e8:a3:c0:aa:e1:1a:8f:fc:ee:05:c0:bd:df:08:c6
+-----BEGIN CERTIFICATE-----
+MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
+TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
+cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
+WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu
+ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY
+MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc
+h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+
+0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U
+A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW
+T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH
+B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC
+B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv
+KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn
+OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn
+jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw
+qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI
+rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
+HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq
+hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
+ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ
+3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK
+NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5
+ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur
+TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC
+jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc
+oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq
+4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA
+mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
+emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
+-----END CERTIFICATE-----
+
+# Issuer: O=FNMT-RCM OU=AC RAIZ FNMT-RCM
+# Subject: O=FNMT-RCM OU=AC RAIZ FNMT-RCM
+# Label: "AC RAIZ FNMT-RCM"
+# Serial: 485876308206448804701554682760554759
+# MD5 Fingerprint: e2:09:04:b4:d3:bd:d1:a0:14:fd:1a:d2:47:c4:57:1d
+# SHA1 Fingerprint: ec:50:35:07:b2:15:c4:95:62:19:e2:a8:9a:5b:42:99:2c:4c:2c:20
+# SHA256 Fingerprint: eb:c5:57:0c:29:01:8c:4d:67:b1:aa:12:7b:af:12:f7:03:b4:61:1e:bc:17:b7:da:b5:57:38:94:17:9b:93:fa
+-----BEGIN CERTIFICATE-----
+MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsx
+CzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJ
+WiBGTk1ULVJDTTAeFw0wODEwMjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJ
+BgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBG
+Tk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALpxgHpMhm5/
+yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcfqQgf
+BBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAz
+WHFctPVrbtQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxF
+tBDXaEAUwED653cXeuYLj2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z
+374jNUUeAlz+taibmSXaXvMiwzn15Cou08YfxGyqxRxqAQVKL9LFwag0Jl1mpdIC
+IfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mwWsXmo8RZZUc1g16p6DUL
+mbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnTtOmlcYF7
+wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peS
+MKGJ47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2
+ZSysV4999AeU14ECll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMet
+UqIJ5G+GR4of6ygnXYMgrwTJbFaai0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUw
+AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFPd9xf3E6Jobd2Sn9R2gzL+H
+YJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1odHRwOi8vd3d3
+LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD
+nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1
+RXxlDPiyN8+sD8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYM
+LVN0V2Ue1bLdI4E7pWYjJ2cJj+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf
+77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrTQfv6MooqtyuGC2mDOL7Nii4LcK2N
+JpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW+YJF1DngoABd15jm
+fZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7Ixjp
+6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp
+1txyM/1d8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B
+9kiABdcPUXmsEKvU7ANm5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wok
+RqEIr9baRRmW1FMdW4R58MD3R++Lj8UGrp1MYp3/RgT408m2ECVAdf4WqslKYIYv
+uu8wd+RU4riEmViAqhOLUTpPSPaLtrM=
+-----END CERTIFICATE-----
+
+# Issuer: CN=Amazon Root CA 1 O=Amazon
+# Subject: CN=Amazon Root CA 1 O=Amazon
+# Label: "Amazon Root CA 1"
+# Serial: 143266978916655856878034712317230054538369994
+# MD5 Fingerprint: 43:c6:bf:ae:ec:fe:ad:2f:18:c6:88:68:30:fc:c8:e6
+# SHA1 Fingerprint: 8d:a7:f9:65:ec:5e:fc:37:91:0f:1c:6e:59:fd:c1:cc:6a:6e:de:16
+# SHA256 Fingerprint: 8e:cd:e6:88:4f:3d:87:b1:12:5b:a3:1a:c3:fc:b1:3d:70:16:de:7f:57:cc:90:4f:e1:cb:97:c6:ae:98:19:6e
+-----BEGIN CERTIFICATE-----
+MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF
+ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6
+b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL
+MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv
+b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj
+ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM
+9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw
+IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6
+VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L
+93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm
+jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
+AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA
+A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI
+U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs
+N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv
+o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU
+5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy
+rqXRfboQnoZsG4q5WTP468SQvvG5
+-----END CERTIFICATE-----
+
+# Issuer: CN=Amazon Root CA 2 O=Amazon
+# Subject: CN=Amazon Root CA 2 O=Amazon
+# Label: "Amazon Root CA 2"
+# Serial: 143266982885963551818349160658925006970653239
+# MD5 Fingerprint: c8:e5:8d:ce:a8:42:e2:7a:c0:2a:5c:7c:9e:26:bf:66
+# SHA1 Fingerprint: 5a:8c:ef:45:d7:a6:98:59:76:7a:8c:8b:44:96:b5:78:cf:47:4b:1a
+# SHA256 Fingerprint: 1b:a5:b2:aa:8c:65:40:1a:82:96:01:18:f8:0b:ec:4f:62:30:4d:83:ce:c4:71:3a:19:c3:9c:01:1e:a4:6d:b4
+-----BEGIN CERTIFICATE-----
+MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwF
+ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6
+b24gUm9vdCBDQSAyMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTEL
+MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv
+b3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK2Wny2cSkxK
+gXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4kHbZ
+W0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg
+1dKmSYXpN+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K
+8nu+NQWpEjTj82R0Yiw9AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r
+2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvdfLC6HM783k81ds8P+HgfajZRRidhW+me
+z/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAExkv8LV/SasrlX6avvDXbR
+8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSSbtqDT6Zj
+mUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz
+7Mt0Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6
++XUyo05f7O0oYtlNc/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI
+0u1ufm8/0i2BWSlmy5A5lREedCf+3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMB
+Af8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSwDPBMMPQFWAJI/TPlUq9LhONm
+UjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oAA7CXDpO8Wqj2
+LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY
++gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kS
+k5Nrp+gvU5LEYFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl
+7uxMMne0nxrpS10gxdr9HIcWxkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygm
+btmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQgj9sAq+uEjonljYE1x2igGOpm/Hl
+urR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbWaQbLU8uz/mtBzUF+
+fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoVYh63
+n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE
+76KlXIx3KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H
+9jVlpNMKVv/1F2Rs76giJUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT
+4PsJYGw=
+-----END CERTIFICATE-----
+
+# Issuer: CN=Amazon Root CA 3 O=Amazon
+# Subject: CN=Amazon Root CA 3 O=Amazon
+# Label: "Amazon Root CA 3"
+# Serial: 143266986699090766294700635381230934788665930
+# MD5 Fingerprint: a0:d4:ef:0b:f7:b5:d8:49:95:2a:ec:f5:c4:fc:81:87
+# SHA1 Fingerprint: 0d:44:dd:8c:3c:8c:1a:1a:58:75:64:81:e9:0f:2e:2a:ff:b3:d2:6e
+# SHA256 Fingerprint: 18:ce:6c:fe:7b:f1:4e:60:b2:e3:47:b8:df:e8:68:cb:31:d0:2e:bb:3a:da:27:15:69:f5:03:43:b4:6d:b3:a4
+-----BEGIN CERTIFICATE-----
+MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5
+MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g
+Um9vdCBDQSAzMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG
+A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg
+Q0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZBf8ANm+gBG1bG8lKl
+ui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjrZt6j
+QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSr
+ttvXBp43rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkr
+BqWTrBqYaGFy+uGh0PsceGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteM
+YyRIHN8wfdVoOw==
+-----END CERTIFICATE-----
+
+# Issuer: CN=Amazon Root CA 4 O=Amazon
+# Subject: CN=Amazon Root CA 4 O=Amazon
+# Label: "Amazon Root CA 4"
+# Serial: 143266989758080763974105200630763877849284878
+# MD5 Fingerprint: 89:bc:27:d5:eb:17:8d:06:6a:69:d5:fd:89:47:b4:cd
+# SHA1 Fingerprint: f6:10:84:07:d6:f8:bb:67:98:0c:c2:e2:44:c2:eb:ae:1c:ef:63:be
+# SHA256 Fingerprint: e3:5d:28:41:9e:d0:20:25:cf:a6:90:38:cd:62:39:62:45:8d:a5:c6:95:fb:de:a3:c2:2b:0b:fb:25:89:70:92
+-----BEGIN CERTIFICATE-----
+MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5
+MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g
+Um9vdCBDQSA0MB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG
+A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg
+Q0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN/sGKe0uoe0ZLY7Bi
+9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri83Bk
+M6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB
+/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WB
+MAoGCCqGSM49BAMDA2gAMGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlw
+CkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1AE47xDqUEpHJWEadIRNyp4iciuRMStuW
+1KyLa2tJElMzrdfkviT8tQp21KW8EA==
+-----END CERTIFICATE-----
+
+# Issuer: CN=LuxTrust Global Root 2 O=LuxTrust S.A.
+# Subject: CN=LuxTrust Global Root 2 O=LuxTrust S.A.
+# Label: "LuxTrust Global Root 2"
+# Serial: 59914338225734147123941058376788110305822489521
+# MD5 Fingerprint: b2:e1:09:00:61:af:f7:f1:91:6f:c4:ad:8d:5e:3b:7c
+# SHA1 Fingerprint: 1e:0e:56:19:0a:d1:8b:25:98:b2:04:44:ff:66:8a:04:17:99:5f:3f
+# SHA256 Fingerprint: 54:45:5f:71:29:c2:0b:14:47:c4:18:f9:97:16:8f:24:c5:8f:c5:02:3b:f5:da:5b:e2:eb:6e:1d:d8:90:2e:d5
+-----BEGIN CERTIFICATE-----
+MIIFwzCCA6ugAwIBAgIUCn6m30tEntpqJIWe5rgV0xZ/u7EwDQYJKoZIhvcNAQEL
+BQAwRjELMAkGA1UEBhMCTFUxFjAUBgNVBAoMDUx1eFRydXN0IFMuQS4xHzAdBgNV
+BAMMFkx1eFRydXN0IEdsb2JhbCBSb290IDIwHhcNMTUwMzA1MTMyMTU3WhcNMzUw
+MzA1MTMyMTU3WjBGMQswCQYDVQQGEwJMVTEWMBQGA1UECgwNTHV4VHJ1c3QgUy5B
+LjEfMB0GA1UEAwwWTHV4VHJ1c3QgR2xvYmFsIFJvb3QgMjCCAiIwDQYJKoZIhvcN
+AQEBBQADggIPADCCAgoCggIBANeFl78RmOnwYoNMPIf5U2o3C/IPPIfOb9wmKb3F
+ibrJgz337spbxm1Jc7TJRqMbNBM/wYlFV/TZsfs2ZUv7COJIcRHIbjuend+JZTem
+hfY7RBi2xjcwYkSSl2l9QjAk5A0MiWtj3sXh306pFGxT4GHO9hcvHTy95iJMHZP1
+EMShduxq3sVs35a0VkBCwGKSMKEtFZSg0iAGCW5qbeXrt77U8PEVfIvmTroTzEsn
+Xpk8F12PgX8zPU/TPxvsXD/wPEx1bvKm1Z3aLQdjAsZy6ZS8TEmVT4hSyNvoaYL4
+zDRbIvCGp4m9SAptZoFtyMhk+wHh9OHe2Z7d21vUKpkmFRseTJIpgp7VkoGSQXAZ
+96Tlk0u8d2cx3Rz9MXANF5kM+Qw5GSoXtTBxVdUPrljhPS80m8+f9niFwpN6cj5m
+j5wWEWCPnolvZ77gR1o7DJpni89Gxq44o/KnvObWhWszJHAiS8sIm7vI+AIpHb4g
+DEa/a4ebsypmQjVGbKq6rfmYe+lQVRQxv7HaLe2ArWgk+2mr2HETMOZns4dA/Yl+
+8kPREd8vZS9kzl8UubG/Mb2HeFpZZYiq/FkySIbWTLkpS5XTdvN3JW1CHDiDTf2j
+X5t/Lax5Gw5CMZdjpPuKadUiDTSQMC6otOBttpSsvItO13D8xTiOZCXhTTmQzsmH
+hFhxAgMBAAGjgagwgaUwDwYDVR0TAQH/BAUwAwEB/zBCBgNVHSAEOzA5MDcGByuB
+KwEBAQowLDAqBggrBgEFBQcCARYeaHR0cHM6Ly9yZXBvc2l0b3J5Lmx1eHRydXN0
+Lmx1MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBT/GCh2+UgFLKGu8SsbK7JT
++Et8szAdBgNVHQ4EFgQU/xgodvlIBSyhrvErGyuyU/hLfLMwDQYJKoZIhvcNAQEL
+BQADggIBAGoZFO1uecEsh9QNcH7X9njJCwROxLHOk3D+sFTAMs2ZMGQXvw/l4jP9
+BzZAcg4atmpZ1gDlaCDdLnINH2pkMSCEfUmmWjfrRcmF9dTHF5kH5ptV5AzoqbTO
+jFu1EVzPig4N1qx3gf4ynCSecs5U89BvolbW7MM3LGVYvlcAGvI1+ut7MV3CwRI9
+loGIlonBWVx65n9wNOeD4rHh4bhY79SV5GCc8JaXcozrhAIuZY+kt9J/Z93I055c
+qqmkoCUUBpvsT34tC38ddfEz2O3OuHVtPlu5mB0xDVbYQw8wkbIEa91WvpWAVWe+
+2M2D2RjuLg+GLZKecBPs3lHJQ3gCpU3I+V/EkVhGFndadKpAvAefMLmx9xIX3eP/
+JEAdemrRTxgKqpAd60Ae36EeRJIQmvKN4dFLRp7oRUKX6kWZ8+xm1QL68qZKJKre
+zrnK+T+Tb/mjuuqlPpmt/f97mfVl7vBZKGfXkJWkE4SphMHozs51k2MavDzq1WQf
+LSoSOcbDWjLtR5EWDrw4wVDej8oqkDQc7kGUnF4ZLvhFSZl0kbAEb+MEWrGrKqv+
+x9CWttrhSmQGbmBNvUJO/3jaJMobtNeWOWyu8Q6qp31IiyBMz2TWuJdGsE7RKlY6
+oJO9r4Ak4Ap+58rVyuiFVdw2KuGUaJPHZnJED4AhMmwlxyOAgwrr
+-----END CERTIFICATE-----
+
+# Issuer: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK OU=Kamu Sertifikasyon Merkezi - Kamu SM
+# Subject: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK OU=Kamu Sertifikasyon Merkezi - Kamu SM
+# Label: "TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1"
+# Serial: 1
+# MD5 Fingerprint: dc:00:81:dc:69:2f:3e:2f:b0:3b:f6:3d:5a:91:8e:49
+# SHA1 Fingerprint: 31:43:64:9b:ec:ce:27:ec:ed:3a:3f:0b:8f:0d:e4:e8:91:dd:ee:ca
+# SHA256 Fingerprint: 46:ed:c3:68:90:46:d5:3a:45:3f:b3:10:4a:b8:0d:ca:ec:65:8b:26:60:ea:16:29:dd:7e:86:79:90:64:87:16
+-----BEGIN CERTIFICATE-----
+MIIEYzCCA0ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCB0jELMAkGA1UEBhMCVFIx
+GDAWBgNVBAcTD0dlYnplIC0gS29jYWVsaTFCMEAGA1UEChM5VHVya2l5ZSBCaWxp
+bXNlbCB2ZSBUZWtub2xvamlrIEFyYXN0aXJtYSBLdXJ1bXUgLSBUVUJJVEFLMS0w
+KwYDVQQLEyRLYW11IFNlcnRpZmlrYXN5b24gTWVya2V6aSAtIEthbXUgU00xNjA0
+BgNVBAMTLVRVQklUQUsgS2FtdSBTTSBTU0wgS29rIFNlcnRpZmlrYXNpIC0gU3Vy
+dW0gMTAeFw0xMzExMjUwODI1NTVaFw00MzEwMjUwODI1NTVaMIHSMQswCQYDVQQG
+EwJUUjEYMBYGA1UEBxMPR2ViemUgLSBLb2NhZWxpMUIwQAYDVQQKEzlUdXJraXll
+IEJpbGltc2VsIHZlIFRla25vbG9qaWsgQXJhc3Rpcm1hIEt1cnVtdSAtIFRVQklU
+QUsxLTArBgNVBAsTJEthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppIC0gS2FtdSBT
+TTE2MDQGA1UEAxMtVFVCSVRBSyBLYW11IFNNIFNTTCBLb2sgU2VydGlmaWthc2kg
+LSBTdXJ1bSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr3UwM6q7
+a9OZLBI3hNmNe5eA027n/5tQlT6QlVZC1xl8JoSNkvoBHToP4mQ4t4y86Ij5iySr
+LqP1N+RAjhgleYN1Hzv/bKjFxlb4tO2KRKOrbEz8HdDc72i9z+SqzvBV96I01INr
+N3wcwv61A+xXzry0tcXtAA9TNypN9E8Mg/uGz8v+jE69h/mniyFXnHrfA2eJLJ2X
+YacQuFWQfw4tJzh03+f92k4S400VIgLI4OD8D62K18lUUMw7D8oWgITQUVbDjlZ/
+iSIzL+aFCr2lqBs23tPcLG07xxO9WSMs5uWk99gL7eqQQESolbuT1dCANLZGeA4f
+AJNG4e7p+exPFwIDAQABo0IwQDAdBgNVHQ4EFgQUZT/HiobGPN08VFw1+DrtUgxH
+V8gwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL
+BQADggEBACo/4fEyjq7hmFxLXs9rHmoJ0iKpEsdeV31zVmSAhHqT5Am5EM2fKifh
+AHe+SMg1qIGf5LgsyX8OsNJLN13qudULXjS99HMpw+0mFZx+CFOKWI3QSyjfwbPf
+IPP54+M638yclNhOT8NrF7f3cuitZjO1JVOr4PhMqZ398g26rrnZqsZr+ZO7rqu4
+lzwDGrpDxpa5RXI4s6ehlj2Re37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c
+8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0jq5Rm+K37DwhuJi1/FwcJsoz7UMCf
+lo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM=
+-----END CERTIFICATE-----
+
+# Issuer: CN=GDCA TrustAUTH R5 ROOT O=GUANG DONG CERTIFICATE AUTHORITY CO.,LTD.
+# Subject: CN=GDCA TrustAUTH R5 ROOT O=GUANG DONG CERTIFICATE AUTHORITY CO.,LTD.
+# Label: "GDCA TrustAUTH R5 ROOT"
+# Serial: 9009899650740120186
+# MD5 Fingerprint: 63:cc:d9:3d:34:35:5c:6f:53:a3:e2:08:70:48:1f:b4
+# SHA1 Fingerprint: 0f:36:38:5b:81:1a:25:c3:9b:31:4e:83:ca:e9:34:66:70:cc:74:b4
+# SHA256 Fingerprint: bf:ff:8f:d0:44:33:48:7d:6a:8a:a6:0c:1a:29:76:7a:9f:c2:bb:b0:5e:42:0f:71:3a:13:b9:92:89:1d:38:93
+-----BEGIN CERTIFICATE-----
+MIIFiDCCA3CgAwIBAgIIfQmX/vBH6nowDQYJKoZIhvcNAQELBQAwYjELMAkGA1UE
+BhMCQ04xMjAwBgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZ
+IENPLixMVEQuMR8wHQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMB4XDTE0
+MTEyNjA1MTMxNVoXDTQwMTIzMTE1NTk1OVowYjELMAkGA1UEBhMCQ04xMjAwBgNV
+BAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZIENPLixMVEQuMR8w
+HQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMIICIjANBgkqhkiG9w0BAQEF
+AAOCAg8AMIICCgKCAgEA2aMW8Mh0dHeb7zMNOwZ+Vfy1YI92hhJCfVZmPoiC7XJj
+Dp6L3TQsAlFRwxn9WVSEyfFrs0yw6ehGXTjGoqcuEVe6ghWinI9tsJlKCvLriXBj
+TnnEt1u9ol2x8kECK62pOqPseQrsXzrj/e+APK00mxqriCZ7VqKChh/rNYmDf1+u
+KU49tm7srsHwJ5uu4/Ts765/94Y9cnrrpftZTqfrlYwiOXnhLQiPzLyRuEH3FMEj
+qcOtmkVEs7LXLM3GKeJQEK5cy4KOFxg2fZfmiJqwTTQJ9Cy5WmYqsBebnh52nUpm
+MUHfP/vFBu8btn4aRjb3ZGM74zkYI+dndRTVdVeSN72+ahsmUPI2JgaQxXABZG12
+ZuGR224HwGGALrIuL4xwp9E7PLOR5G62xDtw8mySlwnNR30YwPO7ng/Wi64HtloP
+zgsMR6flPri9fcebNaBhlzpBdRfMK5Z3KpIhHtmVdiBnaM8Nvd/WHwlqmuLMc3Gk
+L30SgLdTMEZeS1SZD2fJpcjyIMGC7J0R38IC+xo70e0gmu9lZJIQDSri3nDxGGeC
+jGHeuLzRL5z7D9Ar7Rt2ueQ5Vfj4oR24qoAATILnsn8JuLwwoC8N9VKejveSswoA
+HQBUlwbgsQfZxw9cZX08bVlX5O2ljelAU58VS6Bx9hoh49pwBiFYFIeFd3mqgnkC
+AwEAAaNCMEAwHQYDVR0OBBYEFOLJQJ9NzuiaoXzPDj9lxSmIahlRMA8GA1UdEwEB
+/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQDRSVfg
+p8xoWLoBDysZzY2wYUWsEe1jUGn4H3++Fo/9nesLqjJHdtJnJO29fDMylyrHBYZm
+DRd9FBUb1Ov9H5r2XpdptxolpAqzkT9fNqyL7FeoPueBihhXOYV0GkLH6VsTX4/5
+COmSdI31R9KrO9b7eGZONn356ZLpBN79SWP8bfsUcZNnL0dKt7n/HipzcEYwv1ry
+L3ml4Y0M2fmyYzeMN2WFcGpcWwlyua1jPLHd+PwyvzeG5LuOmCd+uh8W4XAR8gPf
+JWIyJyYYMoSf/wA6E7qaTfRPuBRwIrHKK5DOKcFw9C+df/KQHtZa37dG/OaG+svg
+IHZ6uqbL9XzeYqWxi+7egmaKTjowHz+Ay60nugxe19CxVsp3cbK1daFQqUBDF8Io
+2c9Si1vIY9RCPqAzekYu9wogRlR+ak8x8YF+QnQ4ZXMn7sZ8uI7XpTrXmKGcjBBV
+09tL7ECQ8s1uV9JiDnxXk7Gnbc2dg7sq5+W2O3FYrf3RRbxake5TFW/TRQl1brqQ
+XR4EzzffHqhmsYzmIGrv/EhOdJhCrylvLmrH+33RZjEizIYAfmaDDEL0vTSSwxrq
+T8p+ck0LcIymSLumoRT2+1hEmRSuqguTaaApJUqlyyvdimYHFngVV3Eb7PVHhPOe
+MTd61X8kreS8/f3MboPoDKi3QWwH3b08hpcv0g==
+-----END CERTIFICATE-----
+
+# Issuer: CN=TrustCor RootCert CA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority
+# Subject: CN=TrustCor RootCert CA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority
+# Label: "TrustCor RootCert CA-1"
+# Serial: 15752444095811006489
+# MD5 Fingerprint: 6e:85:f1:dc:1a:00:d3:22:d5:b2:b2:ac:6b:37:05:45
+# SHA1 Fingerprint: ff:bd:cd:e7:82:c8:43:5e:3c:6f:26:86:5c:ca:a8:3a:45:5b:c3:0a
+# SHA256 Fingerprint: d4:0e:9c:86:cd:8f:e4:68:c1:77:69:59:f4:9e:a7:74:fa:54:86:84:b6:c4:06:f3:90:92:61:f4:dc:e2:57:5c
+-----BEGIN CERTIFICATE-----
+MIIEMDCCAxigAwIBAgIJANqb7HHzA7AZMA0GCSqGSIb3DQEBCwUAMIGkMQswCQYD
+VQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEk
+MCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U
+cnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRydXN0Q29y
+IFJvb3RDZXJ0IENBLTEwHhcNMTYwMjA0MTIzMjE2WhcNMjkxMjMxMTcyMzE2WjCB
+pDELMAkGA1UEBhMCUEExDzANBgNVBAgMBlBhbmFtYTEUMBIGA1UEBwwLUGFuYW1h
+IENpdHkxJDAiBgNVBAoMG1RydXN0Q29yIFN5c3RlbXMgUy4gZGUgUi5MLjEnMCUG
+A1UECwweVHJ1c3RDb3IgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MR8wHQYDVQQDDBZU
+cnVzdENvciBSb290Q2VydCBDQS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
+CgKCAQEAv463leLCJhJrMxnHQFgKq1mqjQCj/IDHUHuO1CAmujIS2CNUSSUQIpid
+RtLByZ5OGy4sDjjzGiVoHKZaBeYei0i/mJZ0PmnK6bV4pQa81QBeCQryJ3pS/C3V
+seq0iWEk8xoT26nPUu0MJLq5nux+AHT6k61sKZKuUbS701e/s/OojZz0JEsq1pme
+9J7+wH5COucLlVPat2gOkEz7cD+PSiyU8ybdY2mplNgQTsVHCJCZGxdNuWxu72CV
+EY4hgLW9oHPY0LJ3xEXqWib7ZnZ2+AYfYW0PVcWDtxBWcgYHpfOxGgMFZA6dWorW
+hnAbJN7+KIor0Gqw/Hqi3LJ5DotlDwIDAQABo2MwYTAdBgNVHQ4EFgQU7mtJPHo/
+DeOxCbeKyKsZn3MzUOcwHwYDVR0jBBgwFoAU7mtJPHo/DeOxCbeKyKsZn3MzUOcw
+DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQAD
+ggEBACUY1JGPE+6PHh0RU9otRCkZoB5rMZ5NDp6tPVxBb5UrJKF5mDo4Nvu7Zp5I
+/5CQ7z3UuJu0h3U/IJvOcs+hVcFNZKIZBqEHMwwLKeXx6quj7LUKdJDHfXLy11yf
+ke+Ri7fc7Waiz45mO7yfOgLgJ90WmMCV1Aqk5IGadZQ1nJBfiDcGrVmVCrDRZ9MZ
+yonnMlo2HD6CqFqTvsbQZJG2z9m2GM/bftJlo6bEjhcxwft+dtvTheNYsnd6djts
+L1Ac59v2Z3kf9YKVmgenFK+P3CghZwnS1k1aHBkcjndcw5QkPTJrS37UeJSDvjdN
+zl/HHk484IkzlQsPpTLWPFp5LBk=
+-----END CERTIFICATE-----
+
+# Issuer: CN=TrustCor RootCert CA-2 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority
+# Subject: CN=TrustCor RootCert CA-2 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority
+# Label: "TrustCor RootCert CA-2"
+# Serial: 2711694510199101698
+# MD5 Fingerprint: a2:e1:f8:18:0b:ba:45:d5:c7:41:2a:bb:37:52:45:64
+# SHA1 Fingerprint: b8:be:6d:cb:56:f1:55:b9:63:d4:12:ca:4e:06:34:c7:94:b2:1c:c0
+# SHA256 Fingerprint: 07:53:e9:40:37:8c:1b:d5:e3:83:6e:39:5d:ae:a5:cb:83:9e:50:46:f1:bd:0e:ae:19:51:cf:10:fe:c7:c9:65
+-----BEGIN CERTIFICATE-----
+MIIGLzCCBBegAwIBAgIIJaHfyjPLWQIwDQYJKoZIhvcNAQELBQAwgaQxCzAJBgNV
+BAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQw
+IgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRy
+dXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0eTEfMB0GA1UEAwwWVHJ1c3RDb3Ig
+Um9vdENlcnQgQ0EtMjAeFw0xNjAyMDQxMjMyMjNaFw0zNDEyMzExNzI2MzlaMIGk
+MQswCQYDVQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEg
+Q2l0eTEkMCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYD
+VQQLDB5UcnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRy
+dXN0Q29yIFJvb3RDZXJ0IENBLTIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
+AoICAQCnIG7CKqJiJJWQdsg4foDSq8GbZQWU9MEKENUCrO2fk8eHyLAnK0IMPQo+
+QVqedd2NyuCb7GgypGmSaIwLgQ5WoD4a3SwlFIIvl9NkRvRUqdw6VC0xK5mC8tkq
+1+9xALgxpL56JAfDQiDyitSSBBtlVkxs1Pu2YVpHI7TYabS3OtB0PAx1oYxOdqHp
+2yqlO/rOsP9+aij9JxzIsekp8VduZLTQwRVtDr4uDkbIXvRR/u8OYzo7cbrPb1nK
+DOObXUm4TOJXsZiKQlecdu/vvdFoqNL0Cbt3Nb4lggjEFixEIFapRBF37120Hape
+az6LMvYHL1cEksr1/p3C6eizjkxLAjHZ5DxIgif3GIJ2SDpxsROhOdUuxTTCHWKF
+3wP+TfSvPd9cW436cOGlfifHhi5qjxLGhF5DUVCcGZt45vz27Ud+ez1m7xMTiF88
+oWP7+ayHNZ/zgp6kPwqcMWmLmaSISo5uZk3vFsQPeSghYA2FFn3XVDjxklb9tTNM
+g9zXEJ9L/cb4Qr26fHMC4P99zVvh1Kxhe1fVSntb1IVYJ12/+CtgrKAmrhQhJ8Z3
+mjOAPF5GP/fDsaOGM8boXg25NSyqRsGFAnWAoOsk+xWq5Gd/bnc/9ASKL3x74xdh
+8N0JqSDIvgmk0H5Ew7IwSjiqqewYmgeCK9u4nBit2uBGF6zPXQIDAQABo2MwYTAd
+BgNVHQ4EFgQU2f4hQG6UnrybPZx9mCAZ5YwwYrIwHwYDVR0jBBgwFoAU2f4hQG6U
+nrybPZx9mCAZ5YwwYrIwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYw
+DQYJKoZIhvcNAQELBQADggIBAJ5Fngw7tu/hOsh80QA9z+LqBrWyOrsGS2h60COX
+dKcs8AjYeVrXWoSK2BKaG9l9XE1wxaX5q+WjiYndAfrs3fnpkpfbsEZC89NiqpX+
+MWcUaViQCqoL7jcjx1BRtPV+nuN79+TMQjItSQzL/0kMmx40/W5ulop5A7Zv2wnL
+/V9lFDfhOPXzYRZY5LVtDQsEGz9QLX+zx3oaFoBg+Iof6Rsqxvm6ARppv9JYx1RX
+CI/hOWB3S6xZhBqI8d3LT3jX5+EzLfzuQfogsL7L9ziUwOHQhQ+77Sxzq+3+knYa
+ZH9bDTMJBzN7Bj8RpFxwPIXAz+OQqIN3+tvmxYxoZxBnpVIt8MSZj3+/0WvitUfW
+2dCFmU2Umw9Lje4AWkcdEQOsQRivh7dvDDqPys/cA8GiCcjl/YBeyGBCARsaU1q7
+N6a3vLqE6R5sGtRk2tRD/pOLS/IseRYQ1JMLiI+h2IYURpFHmygk71dSTlxCnKr3
+Sewn6EAes6aJInKc9Q0ztFijMDvd1GpUk74aTfOTlPf8hAs/hCBcNANExdqtvArB
+As8e5ZTZ845b2EzwnexhF7sUMlQMAimTHpKG9n/v55IFDlndmQguLvqcAFLTxWYp
+5KeXRKQOKIETNcX2b2TmQcTVL8w0RSXPQQCWPUouwpaYT05KnJe32x+SMsj/D1Fu
+1uwJ
+-----END CERTIFICATE-----
+
+# Issuer: CN=TrustCor ECA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority
+# Subject: CN=TrustCor ECA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority
+# Label: "TrustCor ECA-1"
+# Serial: 9548242946988625984
+# MD5 Fingerprint: 27:92:23:1d:0a:f5:40:7c:e9:e6:6b:9d:d8:f5:e7:6c
+# SHA1 Fingerprint: 58:d1:df:95:95:67:6b:63:c0:f0:5b:1c:17:4d:8b:84:0b:c8:78:bd
+# SHA256 Fingerprint: 5a:88:5d:b1:9c:01:d9:12:c5:75:93:88:93:8c:af:bb:df:03:1a:b2:d4:8e:91:ee:15:58:9b:42:97:1d:03:9c
+-----BEGIN CERTIFICATE-----
+MIIEIDCCAwigAwIBAgIJAISCLF8cYtBAMA0GCSqGSIb3DQEBCwUAMIGcMQswCQYD
+VQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEk
+MCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U
+cnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxFzAVBgNVBAMMDlRydXN0Q29y
+IEVDQS0xMB4XDTE2MDIwNDEyMzIzM1oXDTI5MTIzMTE3MjgwN1owgZwxCzAJBgNV
+BAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQw
+IgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRy
+dXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0eTEXMBUGA1UEAwwOVHJ1c3RDb3Ig
+RUNBLTEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPj+ARtZ+odnbb
+3w9U73NjKYKtR8aja+3+XzP4Q1HpGjORMRegdMTUpwHmspI+ap3tDvl0mEDTPwOA
+BoJA6LHip1GnHYMma6ve+heRK9jGrB6xnhkB1Zem6g23xFUfJ3zSCNV2HykVh0A5
+3ThFEXXQmqc04L/NyFIduUd+Dbi7xgz2c1cWWn5DkR9VOsZtRASqnKmcp0yJF4Ou
+owReUoCLHhIlERnXDH19MURB6tuvsBzvgdAsxZohmz3tQjtQJvLsznFhBmIhVE5/
+wZ0+fyCMgMsq2JdiyIMzkX2woloPV+g7zPIlstR8L+xNxqE6FXrntl019fZISjZF
+ZtS6mFjBAgMBAAGjYzBhMB0GA1UdDgQWBBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAf
+BgNVHSMEGDAWgBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAPBgNVHRMBAf8EBTADAQH/
+MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAQEABT41XBVwm8nHc2Fv
+civUwo/yQ10CzsSUuZQRg2dd4mdsdXa/uwyqNsatR5Nj3B5+1t4u/ukZMjgDfxT2
+AHMsWbEhBuH7rBiVDKP/mZb3Kyeb1STMHd3BOuCYRLDE5D53sXOpZCz2HAF8P11F
+hcCF5yWPldwX8zyfGm6wyuMdKulMY/okYWLW2n62HGz1Ah3UKt1VkOsqEUc8Ll50
+soIipX1TH0XsJ5F95yIW6MBoNtjG8U+ARDL54dHRHareqKucBK+tIA5kmE2la8BI
+WJZpTdwHjFGTot+fDz2LYLSCjaoITmJF4PkL0uDgPFveXHEnJcLmA4GLEFPjx1Wi
+tJ/X5g==
+-----END CERTIFICATE-----
+
+# Issuer: CN=SSL.com Root Certification Authority RSA O=SSL Corporation
+# Subject: CN=SSL.com Root Certification Authority RSA O=SSL Corporation
+# Label: "SSL.com Root Certification Authority RSA"
+# Serial: 8875640296558310041
+# MD5 Fingerprint: 86:69:12:c0:70:f1:ec:ac:ac:c2:d5:bc:a5:5b:a1:29
+# SHA1 Fingerprint: b7:ab:33:08:d1:ea:44:77:ba:14:80:12:5a:6f:bd:a9:36:49:0c:bb
+# SHA256 Fingerprint: 85:66:6a:56:2e:e0:be:5c:e9:25:c1:d8:89:0a:6f:76:a8:7e:c1:6d:4d:7d:5f:29:ea:74:19:cf:20:12:3b:69
+-----BEGIN CERTIFICATE-----
+MIIF3TCCA8WgAwIBAgIIeyyb0xaAMpkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE
+BhMCVVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQK
+DA9TU0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZp
+Y2F0aW9uIEF1dGhvcml0eSBSU0EwHhcNMTYwMjEyMTczOTM5WhcNNDEwMjEyMTcz
+OTM5WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv
+dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNv
+bSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFJTQTCCAiIwDQYJKoZIhvcN
+AQEBBQADggIPADCCAgoCggIBAPkP3aMrfcvQKv7sZ4Wm5y4bunfh4/WvpOz6Sl2R
+xFdHaxh3a3by/ZPkPQ/CFp4LZsNWlJ4Xg4XOVu/yFv0AYvUiCVToZRdOQbngT0aX
+qhvIuG5iXmmxX9sqAn78bMrzQdjt0Oj8P2FI7bADFB0QDksZ4LtO7IZl/zbzXmcC
+C52GVWH9ejjt/uIZALdvoVBidXQ8oPrIJZK0bnoix/geoeOy3ZExqysdBP+lSgQ3
+6YWkMyv94tZVNHwZpEpox7Ko07fKoZOI68GXvIz5HdkihCR0xwQ9aqkpk8zruFvh
+/l8lqjRYyMEjVJ0bmBHDOJx+PYZspQ9AhnwC9FwCTyjLrnGfDzrIM/4RJTXq/LrF
+YD3ZfBjVsqnTdXgDciLKOsMf7yzlLqn6niy2UUb9rwPW6mBo6oUWNmuF6R7As93E
+JNyAKoFBbZQ+yODJgUEAnl6/f8UImKIYLEJAs/lvOCdLToD0PYFH4Ih86hzOtXVc
+US4cK38acijnALXRdMbX5J+tB5O2UzU1/Dfkw/ZdFr4hc96SCvigY2q8lpJqPvi8
+ZVWb3vUNiSYE/CUapiVpy8JtynziWV+XrOvvLsi81xtZPCvM8hnIk2snYxnP/Okm
++Mpxm3+T/jRnhE6Z6/yzeAkzcLpmpnbtG3PrGqUNxCITIJRWCk4sbE6x/c+cCbqi
+M+2HAgMBAAGjYzBhMB0GA1UdDgQWBBTdBAkHovV6fVJTEpKV7jiAJQ2mWTAPBgNV
+HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFN0ECQei9Xp9UlMSkpXuOIAlDaZZMA4G
+A1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAIBgRlCn7Jp0cHh5wYfGV
+cpNxJK1ok1iOMq8bs3AD/CUrdIWQPXhq9LmLpZc7tRiRux6n+UBbkflVma8eEdBc
+Hadm47GUBwwyOabqG7B52B2ccETjit3E+ZUfijhDPwGFpUenPUayvOUiaPd7nNgs
+PgohyC0zrL/FgZkxdMF1ccW+sfAjRfSda/wZY52jvATGGAslu1OJD7OAUN5F7kR/
+q5R4ZJjT9ijdh9hwZXT7DrkT66cPYakylszeu+1jTBi7qUD3oFRuIIhxdRjqerQ0
+cuAjJ3dctpDqhiVAq+8zD8ufgr6iIPv2tS0a5sKFsXQP+8hlAqRSAUfdSSLBv9jr
+a6x+3uxjMxW3IwiPxg+NQVrdjsW5j+VFP3jbutIbQLH+cU0/4IGiul607BXgk90I
+H37hVZkLId6Tngr75qNJvTYw/ud3sqB1l7UtgYgXZSD32pAAn8lSzDLKNXz1PQ/Y
+K9f1JmzJBjSWFupwWRoyeXkLtoh/D1JIPb9s2KJELtFOt3JY04kTlf5Eq/jXixtu
+nLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406ywKBjYZC6VWg3dGq2ktuf
+oYYitmUnDuy2n0Jg5GfCtdpBC8TTi2EbvPofkSvXRAdeuims2cXp71NIWuuA8ShY
+Ic2wBlX7Jz9TkHCpBB5XJ7k=
+-----END CERTIFICATE-----
+
+# Issuer: CN=SSL.com Root Certification Authority ECC O=SSL Corporation
+# Subject: CN=SSL.com Root Certification Authority ECC O=SSL Corporation
+# Label: "SSL.com Root Certification Authority ECC"
+# Serial: 8495723813297216424
+# MD5 Fingerprint: 2e:da:e4:39:7f:9c:8f:37:d1:70:9f:26:17:51:3a:8e
+# SHA1 Fingerprint: c3:19:7c:39:24:e6:54:af:1b:c4:ab:20:95:7a:e2:c3:0e:13:02:6a
+# SHA256 Fingerprint: 34:17:bb:06:cc:60:07:da:1b:96:1c:92:0b:8a:b4:ce:3f:ad:82:0e:4a:a3:0b:9a:cb:c4:a7:4e:bd:ce:bc:65
+-----BEGIN CERTIFICATE-----
+MIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMC
+VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T
+U0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0
+aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNDAzWhcNNDEwMjEyMTgxNDAz
+WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hvdXN0
+b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNvbSBS
+b290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuB
+BAAiA2IABEVuqVDEpiM2nl8ojRfLliJkP9x6jh3MCLOicSS6jkm5BBtHllirLZXI
+7Z4INcgn64mMU1jrYor+8FsPazFSY0E7ic3s7LaNGdM0B9y7xgZ/wkWV7Mt/qCPg
+CemB+vNH06NjMGEwHQYDVR0OBBYEFILRhXMw5zUE044CkvvlpNHEIejNMA8GA1Ud
+EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUgtGFczDnNQTTjgKS++Wk0cQh6M0wDgYD
+VR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCWe+0F+S8T
+kdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+
+gA0z5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl
+-----END CERTIFICATE-----
+
+# Issuer: CN=SSL.com EV Root Certification Authority RSA R2 O=SSL Corporation
+# Subject: CN=SSL.com EV Root Certification Authority RSA R2 O=SSL Corporation
+# Label: "SSL.com EV Root Certification Authority RSA R2"
+# Serial: 6248227494352943350
+# MD5 Fingerprint: e1:1e:31:58:1a:ae:54:53:02:f6:17:6a:11:7b:4d:95
+# SHA1 Fingerprint: 74:3a:f0:52:9b:d0:32:a0:f4:4a:83:cd:d4:ba:a9:7b:7c:2e:c4:9a
+# SHA256 Fingerprint: 2e:7b:f1:6c:c2:24:85:a7:bb:e2:aa:86:96:75:07:61:b0:ae:39:be:3b:2f:e9:d0:cc:6d:4e:f7:34:91:42:5c
+-----BEGIN CERTIFICATE-----
+MIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNV
+BAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UE
+CgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2Vy
+dGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyMB4XDTE3MDUzMTE4MTQzN1oXDTQy
+MDUzMDE4MTQzN1owgYIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4G
+A1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQD
+DC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIy
+MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAjzZlQOHWTcDXtOlG2mvq
+M0fNTPl9fb69LT3w23jhhqXZuglXaO1XPqDQCEGD5yhBJB/jchXQARr7XnAjssuf
+OePPxU7Gkm0mxnu7s9onnQqG6YE3Bf7wcXHswxzpY6IXFJ3vG2fThVUCAtZJycxa
+4bH3bzKfydQ7iEGonL3Lq9ttewkfokxykNorCPzPPFTOZw+oz12WGQvE43LrrdF9
+HSfvkusQv1vrO6/PgN3B0pYEW3p+pKk8OHakYo6gOV7qd89dAFmPZiw+B6KjBSYR
+aZfqhbcPlgtLyEDhULouisv3D5oi53+aNxPN8k0TayHRwMwi8qFG9kRpnMphNQcA
+b9ZhCBHqurj26bNg5U257J8UZslXWNvNh2n4ioYSA0e/ZhN2rHd9NCSFg83XqpyQ
+Gp8hLH94t2S42Oim9HizVcuE0jLEeK6jj2HdzghTreyI/BXkmg3mnxp3zkyPuBQV
+PWKchjgGAGYS5Fl2WlPAApiiECtoRHuOec4zSnaqW4EWG7WK2NAAe15itAnWhmMO
+pgWVSbooi4iTsjQc2KRVbrcc0N6ZVTsj9CLg+SlmJuwgUHfbSguPvuUCYHBBXtSu
+UDkiFCbLsjtzdFVHB3mBOagwE0TlBIqulhMlQg+5U8Sb/M3kHN48+qvWBkofZ6aY
+MBzdLNvcGJVXZsb/XItW9XcCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNV
+HSMEGDAWgBT5YLvU49U09rj1BoAlp3PbRmmonjAdBgNVHQ4EFgQU+WC71OPVNPa4
+9QaAJadz20ZpqJ4wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBW
+s47LCp1Jjr+kxJG7ZhcFUZh1++VQLHqe8RT6q9OKPv+RKY9ji9i0qVQBDb6Thi/5
+Sm3HXvVX+cpVHBK+Rw82xd9qt9t1wkclf7nxY/hoLVUE0fKNsKTPvDxeH3jnpaAg
+cLAExbf3cqfeIg29MyVGjGSSJuM+LmOW2puMPfgYCdcDzH2GguDKBAdRUNf/ktUM
+79qGn5nX67evaOI5JpS6aLe/g9Pqemc9YmeuJeVy6OLk7K4S9ksrPJ/psEDzOFSz
+/bdoyNrGj1E8svuR3Bznm53htw1yj+KkxKl4+esUrMZDBcJlOSgYAsOCsp0FvmXt
+ll9ldDz7CTUue5wT/RsPXcdtgTpWD8w74a8CLyKsRspGPKAcTNZEtF4uXBVmCeEm
+Kf7GUmG6sXP/wwyc5WxqlD8UykAWlYTzWamsX0xhk23RO8yilQwipmdnRC652dKK
+QbNmC1r7fSOl8hqw/96bg5Qu0T/fkreRrwU7ZcegbLHNYhLDkBvjJc40vG93drEQ
+w/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1hlMYegouCRw2n5H9gooi
+S9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX9hwJ1C07
+mKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w==
+-----END CERTIFICATE-----
+
+# Issuer: CN=SSL.com EV Root Certification Authority ECC O=SSL Corporation
+# Subject: CN=SSL.com EV Root Certification Authority ECC O=SSL Corporation
+# Label: "SSL.com EV Root Certification Authority ECC"
+# Serial: 3182246526754555285
+# MD5 Fingerprint: 59:53:22:65:83:42:01:54:c0:ce:42:b9:5a:7c:f2:90
+# SHA1 Fingerprint: 4c:dd:51:a3:d1:f5:20:32:14:b0:c6:c5:32:23:03:91:c7:46:42:6d
+# SHA256 Fingerprint: 22:a2:c1:f7:bd:ed:70:4c:c1:e7:01:b5:f4:08:c3:10:88:0f:e9:56:b5:de:2a:4a:44:f9:9c:87:3a:25:a7:c8
+-----BEGIN CERTIFICATE-----
+MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMC
+VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T
+U0wgQ29ycG9yYXRpb24xNDAyBgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZp
+Y2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNTIzWhcNNDEwMjEyMTgx
+NTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv
+dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NMLmNv
+bSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49
+AgEGBSuBBAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMA
+VIbc/R/fALhBYlzccBYy3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1Kthku
+WnBaBu2+8KGwytAJKaNjMGEwHQYDVR0OBBYEFFvKXuXe0oGqzagtZFG22XKbl+ZP
+MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe5d7SgarNqC1kUbbZcpuX
+5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJN+vp1RPZ
+ytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZg
+h5Mmm7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg==
+-----END CERTIFICATE-----
diff --git a/src/android/test/interop/app/src/main/cpp/grpc-interop.cc b/src/android/test/interop/app/src/main/cpp/grpc-interop.cc
new file mode 100644
index 0000000..bbdc84a
--- /dev/null
+++ b/src/android/test/interop/app/src/main/cpp/grpc-interop.cc
@@ -0,0 +1,124 @@
+/*
+ *
+ * Copyright 2018 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.
+ *
+ */
+
+#include <grpcpp/grpcpp.h>
+#include <jni.h>
+#include <src/core/lib/gpr/env.h>
+
+#include "test/cpp/interop/interop_client.h"
+
+extern "C" JNIEXPORT void JNICALL
+Java_io_grpc_interop_cpp_InteropActivity_configureSslRoots(JNIEnv* env,
+ jobject obj_this,
+ jstring path_raw) {
+ const char* path = env->GetStringUTFChars(path_raw, (jboolean*)0);
+
+ gpr_setenv("GRPC_DEFAULT_SSL_ROOTS_FILE_PATH", path);
+}
+
+std::shared_ptr<grpc::testing::InteropClient> GetClient(const char* host,
+ int port,
+ bool use_tls) {
+ const int host_port_buf_size = 1024;
+ char host_port[host_port_buf_size];
+ snprintf(host_port, host_port_buf_size, "%s:%d", host, port);
+
+ std::shared_ptr<grpc::ChannelCredentials> credentials;
+ if (use_tls) {
+ credentials = grpc::SslCredentials(grpc::SslCredentialsOptions());
+ } else {
+ credentials = grpc::InsecureChannelCredentials();
+ }
+
+ return std::shared_ptr<grpc::testing::InteropClient>(
+ new grpc::testing::InteropClient(
+ grpc::CreateChannel(host_port, credentials), true, false));
+}
+
+extern "C" JNIEXPORT jboolean JNICALL
+Java_io_grpc_interop_cpp_InteropActivity_doEmpty(JNIEnv* env, jobject obj_this,
+ jstring host_raw,
+ jint port_raw,
+ jboolean use_tls_raw) {
+ const char* host = env->GetStringUTFChars(host_raw, (jboolean*)0);
+ int port = static_cast<int>(port_raw);
+ bool use_tls = static_cast<bool>(use_tls_raw);
+
+ return GetClient(host, port, use_tls)->DoEmpty();
+}
+
+extern "C" JNIEXPORT jboolean JNICALL
+Java_io_grpc_interop_cpp_InteropActivity_doLargeUnary(JNIEnv* env,
+ jobject obj_this,
+ jstring host_raw,
+ jint port_raw,
+ jboolean use_tls_raw) {
+ const char* host = env->GetStringUTFChars(host_raw, (jboolean*)0);
+ int port = static_cast<int>(port_raw);
+ bool use_tls = static_cast<bool>(use_tls_raw);
+
+ return GetClient(host, port, use_tls)->DoLargeUnary();
+}
+
+extern "C" JNIEXPORT jboolean JNICALL
+Java_io_grpc_interop_cpp_InteropActivity_doEmptyStream(JNIEnv* env,
+ jobject obj_this,
+ jstring host_raw,
+ jint port_raw,
+ jboolean use_tls_raw) {
+ const char* host = env->GetStringUTFChars(host_raw, (jboolean*)0);
+ int port = static_cast<int>(port_raw);
+ bool use_tls = static_cast<bool>(use_tls_raw);
+
+ return GetClient(host, port, use_tls)->DoEmptyStream();
+}
+
+extern "C" JNIEXPORT jboolean JNICALL
+Java_io_grpc_interop_cpp_InteropActivity_doRequestStreaming(
+ JNIEnv* env, jobject obj_this, jstring host_raw, jint port_raw,
+ jboolean use_tls_raw) {
+ const char* host = env->GetStringUTFChars(host_raw, (jboolean*)0);
+ int port = static_cast<int>(port_raw);
+ bool use_tls = static_cast<bool>(use_tls_raw);
+
+ return GetClient(host, port, use_tls)->DoRequestStreaming();
+}
+
+extern "C" JNIEXPORT jboolean JNICALL
+Java_io_grpc_interop_cpp_InteropActivity_doResponseStreaming(
+ JNIEnv* env, jobject obj_this, jstring host_raw, jint port_raw,
+ jboolean use_tls_raw) {
+ const char* host = env->GetStringUTFChars(host_raw, (jboolean*)0);
+ int port = static_cast<int>(port_raw);
+ bool use_tls = static_cast<bool>(use_tls_raw);
+
+ return GetClient(host, port, use_tls)->DoResponseStreaming();
+}
+
+extern "C" JNIEXPORT jboolean JNICALL
+Java_io_grpc_interop_cpp_InteropActivity_doPingPong(JNIEnv* env,
+ jobject obj_this,
+ jstring host_raw,
+ jint port_raw,
+ jboolean use_tls_raw) {
+ const char* host = env->GetStringUTFChars(host_raw, (jboolean*)0);
+ int port = static_cast<int>(port_raw);
+ bool use_tls = static_cast<bool>(use_tls_raw);
+
+ return GetClient(host, port, use_tls)->DoPingPong();
+}
diff --git a/src/android/test/interop/app/src/main/java/io/grpc/interop/cpp/InteropActivity.java b/src/android/test/interop/app/src/main/java/io/grpc/interop/cpp/InteropActivity.java
new file mode 100644
index 0000000..001f313
--- /dev/null
+++ b/src/android/test/interop/app/src/main/java/io/grpc/interop/cpp/InteropActivity.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2018, gRPC Authors All rights reserved.
+ *
+ * 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.
+ */
+
+package io.grpc.interop.cpp;
+
+import android.content.Context;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.support.v7.app.AppCompatActivity;
+import android.text.TextUtils;
+import android.text.method.ScrollingMovementMethod;
+import android.view.View;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.TextView;
+import java.lang.ref.WeakReference;
+
+public class InteropActivity extends AppCompatActivity {
+
+ static {
+ System.loadLibrary("grpc-interop");
+ }
+
+ private Button sendButton;
+ private EditText hostEdit;
+ private EditText portEdit;
+ private TextView resultText;
+ private GrpcTask grpcTask;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_interop);
+ sendButton = (Button) findViewById(R.id.ping_pong_button);
+ hostEdit = (EditText) findViewById(R.id.host_edit_text);
+ portEdit = (EditText) findViewById(R.id.port_edit_text);
+ resultText = (TextView) findViewById(R.id.grpc_result_text);
+ resultText.setMovementMethod(new ScrollingMovementMethod());
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ if (grpcTask != null) {
+ grpcTask.cancel(true);
+ grpcTask = null;
+ }
+ }
+
+ public void doPingPong(View view) {
+ ((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE))
+ .hideSoftInputFromWindow(hostEdit.getWindowToken(), 0);
+ sendButton.setEnabled(false);
+ resultText.setText("");
+ grpcTask = new GrpcTask(this);
+ grpcTask.executeOnExecutor(
+ AsyncTask.THREAD_POOL_EXECUTOR,
+ hostEdit.getText().toString(),
+ portEdit.getText().toString());
+ }
+
+ private static class GrpcTask extends AsyncTask<String, Void, String> {
+ private final WeakReference<InteropActivity> activityReference;
+
+ private GrpcTask(InteropActivity activity) {
+ this.activityReference = new WeakReference<InteropActivity>(activity);
+ }
+
+ @Override
+ protected String doInBackground(String... params) {
+ String host = params[0];
+ String portStr = params[1];
+ int port = TextUtils.isEmpty(portStr) ? 50051 : Integer.valueOf(portStr);
+ // TODO(ericgribkoff) Support other test cases in the app UI
+ if (doPingPong(host, port, false)) {
+ return "Success";
+ } else {
+ return "Failure";
+ }
+ }
+
+ @Override
+ protected void onPostExecute(String result) {
+ InteropActivity activity = activityReference.get();
+ if (activity == null || isCancelled()) {
+ return;
+ }
+ TextView resultText = (TextView) activity.findViewById(R.id.grpc_result_text);
+ Button sendButton = (Button) activity.findViewById(R.id.ping_pong_button);
+ resultText.setText(result);
+ sendButton.setEnabled(true);
+ }
+ }
+
+ public static native void configureSslRoots(String path);
+
+ public static native boolean doEmpty(String host, int port, boolean useTls);
+
+ public static native boolean doLargeUnary(String host, int port, boolean useTls);
+
+ public static native boolean doEmptyStream(String host, int port, boolean useTls);
+
+ public static native boolean doRequestStreaming(String host, int port, boolean useTls);
+
+ public static native boolean doResponseStreaming(String host, int port, boolean useTls);
+
+ public static native boolean doPingPong(String host, int port, boolean useTls);
+}
diff --git a/src/android/test/interop/app/src/main/res/layout/activity_interop.xml b/src/android/test/interop/app/src/main/res/layout/activity_interop.xml
new file mode 100644
index 0000000..81ec342
--- /dev/null
+++ b/src/android/test/interop/app/src/main/res/layout/activity_interop.xml
@@ -0,0 +1,48 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ tools:context=".InteropActivity"
+ android:orientation="vertical" >
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+ <EditText
+ android:id="@+id/host_edit_text"
+ android:layout_weight="2"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:hint="Enter Host" />
+ <EditText
+ android:id="@+id/port_edit_text"
+ android:layout_weight="1"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:inputType="numberDecimal"
+ android:hint="Enter Port" />
+ </LinearLayout>
+
+ <Button
+ android:id="@+id/ping_pong_button"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:onClick="doPingPong"
+ android:text="Ping Pong" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="12dp"
+ android:paddingBottom="12dp"
+ android:textSize="16sp"
+ android:text="Result:" />
+
+ <TextView
+ android:id="@+id/grpc_result_text"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:scrollbars = "vertical"
+ android:textSize="16sp" />
+
+</LinearLayout>
diff --git a/src/android/test/interop/app/src/main/res/mipmap-hdpi/ic_launcher.png b/src/android/test/interop/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..cde69bc
--- /dev/null
+++ b/src/android/test/interop/app/src/main/res/mipmap-hdpi/ic_launcher.png
Binary files differ
diff --git a/src/android/test/interop/app/src/main/res/mipmap-mdpi/ic_launcher.png b/src/android/test/interop/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..c133a0c
--- /dev/null
+++ b/src/android/test/interop/app/src/main/res/mipmap-mdpi/ic_launcher.png
Binary files differ
diff --git a/src/android/test/interop/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/src/android/test/interop/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..bfa42f0
--- /dev/null
+++ b/src/android/test/interop/app/src/main/res/mipmap-xhdpi/ic_launcher.png
Binary files differ
diff --git a/src/android/test/interop/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/src/android/test/interop/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..324e72c
--- /dev/null
+++ b/src/android/test/interop/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/src/android/test/interop/app/src/main/res/values/strings.xml b/src/android/test/interop/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..e63210b
--- /dev/null
+++ b/src/android/test/interop/app/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+<resources>
+ <string name="app_name">gRPC C++ Interop App</string>
+</resources>
diff --git a/src/android/test/interop/build.gradle b/src/android/test/interop/build.gradle
new file mode 100644
index 0000000..bd5f337
--- /dev/null
+++ b/src/android/test/interop/build.gradle
@@ -0,0 +1,24 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ repositories {
+ google()
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:3.0.1'
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ google()
+ jcenter()
+ }
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
diff --git a/src/android/test/interop/gradle.properties b/src/android/test/interop/gradle.properties
new file mode 100644
index 0000000..aac7c9b
--- /dev/null
+++ b/src/android/test/interop/gradle.properties
@@ -0,0 +1,17 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx1536m
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
diff --git a/src/android/test/interop/gradle/wrapper/gradle-wrapper.jar b/src/android/test/interop/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..13372ae
--- /dev/null
+++ b/src/android/test/interop/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/src/android/test/interop/gradle/wrapper/gradle-wrapper.properties b/src/android/test/interop/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..4c81831
--- /dev/null
+++ b/src/android/test/interop/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Thu Jan 25 11:45:30 PST 2018
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
diff --git a/src/android/test/interop/gradlew b/src/android/test/interop/gradlew
new file mode 100755
index 0000000..9d82f78
--- /dev/null
+++ b/src/android/test/interop/gradlew
@@ -0,0 +1,160 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/src/android/test/interop/gradlew.bat b/src/android/test/interop/gradlew.bat
new file mode 100644
index 0000000..8a0b282
--- /dev/null
+++ b/src/android/test/interop/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/src/android/test/interop/settings.gradle b/src/android/test/interop/settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/src/android/test/interop/settings.gradle
@@ -0,0 +1 @@
+include ':app'
diff --git a/src/compiler/node_generator.cc b/src/compiler/node_generator.cc
index 661587c..a430628 100644
--- a/src/compiler/node_generator.cc
+++ b/src/compiler/node_generator.cc
@@ -20,6 +20,7 @@
#include "src/compiler/config.h"
#include "src/compiler/generator_helpers.h"
+#include "src/compiler/node_generator.h"
#include "src/compiler/node_generator_helpers.h"
using grpc::protobuf::Descriptor;
@@ -119,7 +120,8 @@
}
// Prints out the message serializer and deserializer functions
-void PrintMessageTransformer(const Descriptor* descriptor, Printer* out) {
+void PrintMessageTransformer(const Descriptor* descriptor, Printer* out,
+ const Parameters& params) {
map<grpc::string, grpc::string> template_vars;
grpc::string full_name = descriptor->full_name();
template_vars["identifier_name"] = MessageIdentifierName(full_name);
@@ -134,7 +136,12 @@
"throw new Error('Expected argument of type $name$');\n");
out->Outdent();
out->Print("}\n");
- out->Print("return new Buffer(arg.serializeBinary());\n");
+ if (params.minimum_node_version > 5) {
+ // Node version is > 5, we should use Buffer.from
+ out->Print("return Buffer.from(arg.serializeBinary());\n");
+ } else {
+ out->Print("return new Buffer(arg.serializeBinary());\n");
+ }
out->Outdent();
out->Print("}\n\n");
@@ -219,12 +226,13 @@
out->Print("\n");
}
-void PrintTransformers(const FileDescriptor* file, Printer* out) {
+void PrintTransformers(const FileDescriptor* file, Printer* out,
+ const Parameters& params) {
map<grpc::string, const Descriptor*> messages = GetAllMessages(file);
for (std::map<grpc::string, const Descriptor*>::iterator it =
messages.begin();
it != messages.end(); it++) {
- PrintMessageTransformer(it->second, out);
+ PrintMessageTransformer(it->second, out, params);
}
out->Print("\n");
}
@@ -236,7 +244,8 @@
}
} // namespace
-grpc::string GenerateFile(const FileDescriptor* file) {
+grpc::string GenerateFile(const FileDescriptor* file,
+ const Parameters& params) {
grpc::string output;
{
StringOutputStream output_stream(&output);
@@ -257,7 +266,7 @@
PrintImports(file, &out);
- PrintTransformers(file, &out);
+ PrintTransformers(file, &out, params);
PrintServices(file, &out);
diff --git a/src/compiler/node_generator.h b/src/compiler/node_generator.h
index a9ffe75..f3a5315 100644
--- a/src/compiler/node_generator.h
+++ b/src/compiler/node_generator.h
@@ -23,7 +23,14 @@
namespace grpc_node_generator {
-grpc::string GenerateFile(const grpc::protobuf::FileDescriptor* file);
+// Contains all the parameters that are parsed from the command line.
+struct Parameters {
+ // Sets the earliest version of nodejs that needs to be supported.
+ int minimum_node_version;
+};
+
+grpc::string GenerateFile(const grpc::protobuf::FileDescriptor* file,
+ const Parameters& params);
} // namespace grpc_node_generator
diff --git a/src/compiler/node_plugin.cc b/src/compiler/node_plugin.cc
index bc38e90..0d19d8e 100644
--- a/src/compiler/node_plugin.cc
+++ b/src/compiler/node_plugin.cc
@@ -36,7 +36,27 @@
const grpc::string& parameter,
grpc::protobuf::compiler::GeneratorContext* context,
grpc::string* error) const {
- grpc::string code = GenerateFile(file);
+ grpc_node_generator::Parameters generator_parameters;
+ generator_parameters.minimum_node_version = 4;
+
+ if (!parameter.empty()) {
+ std::vector<grpc::string> parameters_list =
+ grpc_generator::tokenize(parameter, ",");
+ for (auto parameter_string = parameters_list.begin();
+ parameter_string != parameters_list.end(); parameter_string++) {
+ std::vector<grpc::string> param =
+ grpc_generator::tokenize(*parameter_string, "=");
+ if (param[0] == "minimum_node_version") {
+ sscanf(param[1].c_str(), "%d",
+ &generator_parameters.minimum_node_version);
+ } else {
+ *error = grpc::string("Unknown parameter: ") + *parameter_string;
+ return false;
+ }
+ }
+ }
+
+ grpc::string code = GenerateFile(file, generator_parameters);
if (code.size() == 0) {
return true;
}
diff --git a/src/compiler/objective_c_generator.cc b/src/compiler/objective_c_generator.cc
index ffdeb8f..39f68cb 100644
--- a/src/compiler/objective_c_generator.cc
+++ b/src/compiler/objective_c_generator.cc
@@ -206,7 +206,7 @@
}
}
for (auto one_class : classes) {
- output += " @class " + one_class + ";\n";
+ output += "@class " + one_class + ";\n";
}
return output;
diff --git a/src/compiler/objective_c_plugin.cc b/src/compiler/objective_c_plugin.cc
index 76703d7..f0fe368 100644
--- a/src/compiler/objective_c_plugin.cc
+++ b/src/compiler/objective_c_plugin.cc
@@ -118,11 +118,11 @@
Write(context, file_name + ".pbrpc.h",
PreprocIfNot(kForwardDeclare, imports) + "\n" +
PreprocIfNot(kProtocolOnly, system_imports) + "\n" +
- PreprocIfElse(kForwardDeclare, class_declarations,
- class_imports) +
- "\n" + forward_declarations + "\n" + kNonNullBegin + "\n" +
- protocols + "\n" + PreprocIfNot(kProtocolOnly, interfaces) +
- "\n" + kNonNullEnd + "\n");
+ class_declarations + "\n" +
+ PreprocIfNot(kForwardDeclare, class_imports) + "\n" +
+ forward_declarations + "\n" + kNonNullBegin + "\n" + protocols +
+ "\n" + PreprocIfNot(kProtocolOnly, interfaces) + "\n" +
+ kNonNullEnd + "\n");
}
{
diff --git a/src/compiler/ruby_generator.cc b/src/compiler/ruby_generator.cc
index e81dea6..c7af9c3 100644
--- a/src/compiler/ruby_generator.cc
+++ b/src/compiler/ruby_generator.cc
@@ -73,7 +73,7 @@
// Begin the service module
std::map<grpc::string, grpc::string> module_vars = ListToDict({
"module.name",
- CapitalizeFirst(service->name()),
+ Modularize(service->name()),
});
out->Print(module_vars, "module $module.name$\n");
out->Indent();
diff --git a/src/compiler/ruby_generator_string-inl.h b/src/compiler/ruby_generator_string-inl.h
index fb42978..ecfe796 100644
--- a/src/compiler/ruby_generator_string-inl.h
+++ b/src/compiler/ruby_generator_string-inl.h
@@ -81,13 +81,23 @@
return true;
}
-// CapitalizeFirst capitalizes the first char in a string.
-inline grpc::string CapitalizeFirst(grpc::string s) {
+// Modularize converts a string into a ruby module compatible name
+inline grpc::string Modularize(grpc::string s) {
if (s.empty()) {
return s;
}
- s[0] = ::toupper(s[0]);
- return s;
+ grpc::string new_string = "";
+ bool was_last_underscore = false;
+ new_string.append(1, ::toupper(s[0]));
+ for (grpc::string::size_type i = 1; i < s.size(); ++i) {
+ if (was_last_underscore && s[i] != '_') {
+ new_string.append(1, ::toupper(s[i]));
+ } else if (s[i] != '_') {
+ new_string.append(1, s[i]);
+ }
+ was_last_underscore = s[i] == '_';
+ }
+ return new_string;
}
// RubyTypeOf updates a proto type to the required ruby equivalent.
@@ -106,7 +116,7 @@
res += "::"; // switch '.' to the ruby module delim
}
if (i < prefixes_and_type.size() - 1) {
- res += CapitalizeFirst(prefixes_and_type[i]); // capitalize pkgs
+ res += Modularize(prefixes_and_type[i]); // capitalize pkgs
} else {
res += prefixes_and_type[i];
}
diff --git a/src/core/ext/filters/client_channel/OWNERS b/src/core/ext/filters/client_channel/OWNERS
index 8f5e928..c8760d9 100644
--- a/src/core/ext/filters/client_channel/OWNERS
+++ b/src/core/ext/filters/client_channel/OWNERS
@@ -1,4 +1,4 @@
set noparent
@markdroth
@dgquintas
-@a11r
+@AspirinSJL
diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc
index 67dd3a1..80a647f 100644
--- a/src/core/ext/filters/client_channel/client_channel.cc
+++ b/src/core/ext/filters/client_channel/client_channel.cc
@@ -63,6 +63,7 @@
#include "src/core/lib/transport/status_metadata.h"
using grpc_core::internal::ClientChannelMethodParams;
+using grpc_core::internal::ServerRetryThrottleData;
/* Client channel implementation */
@@ -99,7 +100,7 @@
/** currently active load balancer */
grpc_core::OrphanablePtr<grpc_core::LoadBalancingPolicy> lb_policy;
/** retry throttle data */
- grpc_server_retry_throttle_data* retry_throttle_data;
+ grpc_core::RefCountedPtr<ServerRetryThrottleData> retry_throttle_data;
/** maps method names to method_parameters structs */
grpc_core::RefCountedPtr<MethodParamsTable> method_params_table;
/** incoming resolver result - set by resolver.next() */
@@ -173,7 +174,7 @@
}
}
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG, "chand=%p: setting connectivity state to %s", chand,
+ gpr_log(GPR_INFO, "chand=%p: setting connectivity state to %s", chand,
grpc_connectivity_state_name(state));
}
grpc_connectivity_state_set(&chand->state_tracker, state, error, reason);
@@ -185,7 +186,7 @@
/* check if the notification is for the latest policy */
if (w->lb_policy == w->chand->lb_policy.get()) {
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG, "chand=%p: lb_policy=%p state changed to %s", w->chand,
+ gpr_log(GPR_INFO, "chand=%p: lb_policy=%p state changed to %s", w->chand,
w->lb_policy, grpc_connectivity_state_name(w->state));
}
set_channel_connectivity_state_locked(w->chand, w->state,
@@ -214,7 +215,7 @@
static void start_resolving_locked(channel_data* chand) {
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG, "chand=%p: starting name resolution", chand);
+ gpr_log(GPR_INFO, "chand=%p: starting name resolution", chand);
}
GPR_ASSERT(!chand->started_resolving);
chand->started_resolving = true;
@@ -225,7 +226,7 @@
typedef struct {
char* server_name;
- grpc_server_retry_throttle_data* retry_throttle_data;
+ grpc_core::RefCountedPtr<ServerRetryThrottleData> retry_throttle_data;
} service_config_parsing_state;
static void parse_retry_throttle_params(
@@ -278,7 +279,7 @@
}
}
parsing_state->retry_throttle_data =
- grpc_retry_throttle_map_get_data_for_server(
+ grpc_core::internal::ServerRetryThrottleMap::GetDataForServer(
parsing_state->server_name, max_milli_tokens, milli_token_ratio);
}
}
@@ -296,7 +297,7 @@
return;
}
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG, "chand=%p: started name re-resolving", chand);
+ gpr_log(GPR_INFO, "chand=%p: started name re-resolving", chand);
}
chand->resolver->RequestReresolutionLocked();
// Give back the closure to the LB policy.
@@ -310,7 +311,7 @@
static void on_resolver_result_changed_locked(void* arg, grpc_error* error) {
channel_data* chand = static_cast<channel_data*>(arg);
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"chand=%p: got resolver result: resolver_result=%p error=%s", chand,
chand->resolver_result, grpc_error_string(error));
}
@@ -321,7 +322,7 @@
bool lb_policy_name_changed = false;
grpc_core::OrphanablePtr<grpc_core::LoadBalancingPolicy> new_lb_policy;
char* service_config_json = nullptr;
- grpc_server_retry_throttle_data* retry_throttle_data = nullptr;
+ grpc_core::RefCountedPtr<ServerRetryThrottleData> retry_throttle_data;
grpc_core::RefCountedPtr<MethodParamsTable> method_params_table;
if (chand->resolver_result != nullptr) {
if (chand->resolver != nullptr) {
@@ -421,7 +422,7 @@
service_config->ParseGlobalParams(parse_retry_throttle_params,
&parsing_state);
grpc_uri_destroy(uri);
- retry_throttle_data = parsing_state.retry_throttle_data;
+ retry_throttle_data = std::move(parsing_state.retry_throttle_data);
}
method_params_table = service_config->CreateMethodConfigTable(
ClientChannelMethodParams::CreateFromJson);
@@ -430,7 +431,7 @@
}
}
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"chand=%p: resolver result: lb_policy_name=\"%s\"%s, "
"service_config=\"%s\"",
chand, lb_policy_name_dup,
@@ -452,10 +453,7 @@
}
gpr_mu_unlock(&chand->info_mu);
// Swap out the retry throttle data.
- if (chand->retry_throttle_data != nullptr) {
- grpc_server_retry_throttle_data_unref(chand->retry_throttle_data);
- }
- chand->retry_throttle_data = retry_throttle_data;
+ chand->retry_throttle_data = std::move(retry_throttle_data);
// Swap out the method params table.
chand->method_params_table = std::move(method_params_table);
// If we have a new LB policy or are shutting down (in which case
@@ -468,7 +466,7 @@
chand->resolver == nullptr) {
if (chand->lb_policy != nullptr) {
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG, "chand=%p: unreffing lb_policy=%p", chand,
+ gpr_log(GPR_INFO, "chand=%p: unreffing lb_policy=%p", chand,
chand->lb_policy.get());
}
grpc_pollset_set_del_pollset_set(chand->lb_policy->interested_parties(),
@@ -482,11 +480,11 @@
// error or shutdown.
if (error != GRPC_ERROR_NONE || chand->resolver == nullptr) {
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG, "chand=%p: shutting down", chand);
+ gpr_log(GPR_INFO, "chand=%p: shutting down", chand);
}
if (chand->resolver != nullptr) {
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG, "chand=%p: shutting down resolver", chand);
+ gpr_log(GPR_INFO, "chand=%p: shutting down resolver", chand);
}
chand->resolver.reset();
}
@@ -508,7 +506,7 @@
GRPC_ERROR_CREATE_FROM_STATIC_STRING("No load balancing policy");
if (lb_policy_created) {
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG, "chand=%p: initializing new LB policy", chand);
+ gpr_log(GPR_INFO, "chand=%p: initializing new LB policy", chand);
}
GRPC_ERROR_UNREF(state_error);
state = chand->lb_policy->CheckConnectivityLocked(&state_error);
@@ -725,12 +723,8 @@
}
gpr_free(chand->info_lb_policy_name);
gpr_free(chand->info_service_config_json);
- if (chand->retry_throttle_data != nullptr) {
- grpc_server_retry_throttle_data_unref(chand->retry_throttle_data);
- }
- if (chand->method_params_table != nullptr) {
- chand->method_params_table.reset();
- }
+ chand->retry_throttle_data.reset();
+ chand->method_params_table.reset();
grpc_client_channel_stop_backup_polling(chand->interested_parties);
grpc_connectivity_state_destroy(&chand->state_tracker);
grpc_pollset_set_destroy(chand->interested_parties);
@@ -848,10 +842,11 @@
bool completed_recv_trailing_metadata : 1;
// State for callback processing.
bool retry_dispatched : 1;
- bool recv_initial_metadata_ready_deferred : 1;
- bool recv_message_ready_deferred : 1;
+ subchannel_batch_data* recv_initial_metadata_ready_deferred_batch;
grpc_error* recv_initial_metadata_error;
+ subchannel_batch_data* recv_message_ready_deferred_batch;
grpc_error* recv_message_error;
+ subchannel_batch_data* recv_trailing_metadata_internal_batch;
} subchannel_call_retry_state;
// Pending batches stored in call data.
@@ -883,7 +878,7 @@
grpc_call_stack* owning_call;
grpc_call_combiner* call_combiner;
- grpc_server_retry_throttle_data* retry_throttle_data;
+ grpc_core::RefCountedPtr<ServerRetryThrottleData> retry_throttle_data;
grpc_core::RefCountedPtr<ClientChannelMethodParams> method_params;
grpc_subchannel_call* subchannel_call;
@@ -930,7 +925,9 @@
// Note: We inline the cache for the first 3 send_message ops and use
// dynamic allocation after that. This number was essentially picked
// at random; it could be changed in the future to tune performance.
- grpc_core::InlinedVector<grpc_core::ByteStreamCache*, 3> send_messages;
+ grpc_core::ManualConstructor<
+ grpc_core::InlinedVector<grpc_core::ByteStreamCache*, 3>>
+ send_messages;
// send_trailing_metadata
bool seen_send_trailing_metadata;
grpc_linked_mdelem* send_trailing_metadata_storage;
@@ -980,7 +977,7 @@
gpr_arena_alloc(calld->arena, sizeof(grpc_core::ByteStreamCache)));
new (cache) grpc_core::ByteStreamCache(
std::move(batch->payload->send_message.send_message));
- calld->send_messages.push_back(cache);
+ calld->send_messages->push_back(cache);
}
// Save metadata batch for send_trailing_metadata ops.
if (batch->send_trailing_metadata) {
@@ -998,6 +995,39 @@
}
}
+// Frees cached send_initial_metadata.
+static void free_cached_send_initial_metadata(channel_data* chand,
+ call_data* calld) {
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_INFO,
+ "chand=%p calld=%p: destroying calld->send_initial_metadata", chand,
+ calld);
+ }
+ grpc_metadata_batch_destroy(&calld->send_initial_metadata);
+}
+
+// Frees cached send_message at index idx.
+static void free_cached_send_message(channel_data* chand, call_data* calld,
+ size_t idx) {
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_INFO,
+ "chand=%p calld=%p: destroying calld->send_messages[%" PRIuPTR "]",
+ chand, calld, idx);
+ }
+ (*calld->send_messages)[idx]->Destroy();
+}
+
+// Frees cached send_trailing_metadata.
+static void free_cached_send_trailing_metadata(channel_data* chand,
+ call_data* calld) {
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_INFO,
+ "chand=%p calld=%p: destroying calld->send_trailing_metadata",
+ chand, calld);
+ }
+ grpc_metadata_batch_destroy(&calld->send_trailing_metadata);
+}
+
// Frees cached send ops that have already been completed after
// committing the call.
static void free_cached_send_op_data_after_commit(
@@ -1005,19 +1035,13 @@
channel_data* chand = static_cast<channel_data*>(elem->channel_data);
call_data* calld = static_cast<call_data*>(elem->call_data);
if (retry_state->completed_send_initial_metadata) {
- grpc_metadata_batch_destroy(&calld->send_initial_metadata);
+ free_cached_send_initial_metadata(chand, calld);
}
for (size_t i = 0; i < retry_state->completed_send_message_count; ++i) {
- if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG,
- "chand=%p calld=%p: destroying calld->send_messages[%" PRIuPTR
- "]",
- chand, calld, i);
- }
- calld->send_messages[i]->Destroy();
+ free_cached_send_message(chand, calld, i);
}
if (retry_state->completed_send_trailing_metadata) {
- grpc_metadata_batch_destroy(&calld->send_trailing_metadata);
+ free_cached_send_trailing_metadata(chand, calld);
}
}
@@ -1029,20 +1053,14 @@
channel_data* chand = static_cast<channel_data*>(elem->channel_data);
call_data* calld = static_cast<call_data*>(elem->call_data);
if (batch_data->batch.send_initial_metadata) {
- grpc_metadata_batch_destroy(&calld->send_initial_metadata);
+ free_cached_send_initial_metadata(chand, calld);
}
if (batch_data->batch.send_message) {
- if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG,
- "chand=%p calld=%p: destroying calld->send_messages[%" PRIuPTR
- "]",
- chand, calld, retry_state->completed_send_message_count - 1);
- }
- calld->send_messages[retry_state->completed_send_message_count - 1]
- ->Destroy();
+ free_cached_send_message(chand, calld,
+ retry_state->completed_send_message_count - 1);
}
if (batch_data->batch.send_trailing_metadata) {
- grpc_metadata_batch_destroy(&calld->send_trailing_metadata);
+ free_cached_send_trailing_metadata(chand, calld);
}
}
@@ -1070,7 +1088,7 @@
call_data* calld = static_cast<call_data*>(elem->call_data);
const size_t idx = get_batch_index(batch);
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"chand=%p calld=%p: adding pending batch at index %" PRIuPTR, chand,
calld, idx);
}
@@ -1098,7 +1116,7 @@
}
if (calld->bytes_buffered_for_retry > chand->per_rpc_retry_buffer_size) {
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"chand=%p calld=%p: exceeded retry buffer size, committing",
chand, calld);
}
@@ -1113,7 +1131,7 @@
// retries are disabled so that we don't bother with retry overhead.
if (calld->num_attempts_completed == 0) {
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"chand=%p calld=%p: disabling retries before first attempt",
chand, calld);
}
@@ -1160,7 +1178,7 @@
for (size_t i = 0; i < GPR_ARRAY_SIZE(calld->pending_batches); ++i) {
if (calld->pending_batches[i].batch != nullptr) ++num_batches;
}
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"chand=%p calld=%p: failing %" PRIuPTR " pending batches: %s",
elem->channel_data, calld, num_batches, grpc_error_string(error));
}
@@ -1222,7 +1240,7 @@
for (size_t i = 0; i < GPR_ARRAY_SIZE(calld->pending_batches); ++i) {
if (calld->pending_batches[i].batch != nullptr) ++num_batches;
}
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"chand=%p calld=%p: starting %" PRIuPTR
" pending batches on subchannel_call=%p",
chand, calld, num_batches, calld->subchannel_call);
@@ -1267,7 +1285,7 @@
(!batch->recv_message ||
batch->payload->recv_message.recv_message_ready == nullptr)) {
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG, "chand=%p calld=%p: clearing pending batch", chand,
+ gpr_log(GPR_INFO, "chand=%p calld=%p: clearing pending batch", chand,
calld);
}
pending_batch_clear(calld, pending);
@@ -1286,7 +1304,8 @@
return false;
}
if (pending->batch->send_message &&
- retry_state->completed_send_message_count < calld->send_messages.size()) {
+ retry_state->completed_send_message_count <
+ calld->send_messages->size()) {
return false;
}
if (pending->batch->send_trailing_metadata &&
@@ -1321,7 +1340,7 @@
return true;
}
if (pending->batch->send_message &&
- retry_state->started_send_message_count < calld->send_messages.size()) {
+ retry_state->started_send_message_count < calld->send_messages->size()) {
return true;
}
if (pending->batch->send_trailing_metadata &&
@@ -1356,7 +1375,7 @@
if (calld->retry_committed) return;
calld->retry_committed = true;
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG, "chand=%p calld=%p: committing retries", chand, calld);
+ gpr_log(GPR_INFO, "chand=%p calld=%p: committing retries", chand, calld);
}
if (retry_state != nullptr) {
free_cached_send_op_data_after_commit(elem, retry_state);
@@ -1401,7 +1420,7 @@
next_attempt_time = calld->retry_backoff->NextAttemptTime();
}
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"chand=%p calld=%p: retrying failed call in %" PRIuPTR " ms", chand,
calld, next_attempt_time - grpc_core::ExecCtx::Get()->Now());
}
@@ -1435,7 +1454,7 @@
batch_data->subchannel_call));
if (retry_state->retry_dispatched) {
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG, "chand=%p calld=%p: retry already dispatched", chand,
+ gpr_log(GPR_INFO, "chand=%p calld=%p: retry already dispatched", chand,
calld);
}
return true;
@@ -1443,16 +1462,18 @@
}
// Check status.
if (status == GRPC_STATUS_OK) {
- grpc_server_retry_throttle_data_record_success(calld->retry_throttle_data);
+ if (calld->retry_throttle_data != nullptr) {
+ calld->retry_throttle_data->RecordSuccess();
+ }
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG, "chand=%p calld=%p: call succeeded", chand, calld);
+ gpr_log(GPR_INFO, "chand=%p calld=%p: call succeeded", chand, calld);
}
return false;
}
// Status is not OK. Check whether the status is retryable.
if (!retry_policy->retryable_status_codes.Contains(status)) {
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"chand=%p calld=%p: status %s not configured as retryable", chand,
calld, grpc_status_code_to_string(status));
}
@@ -1465,17 +1486,17 @@
// things like failures due to malformed requests (INVALID_ARGUMENT).
// Conversely, it's important for this to come before the remaining
// checks, so that we don't fail to record failures due to other factors.
- if (!grpc_server_retry_throttle_data_record_failure(
- calld->retry_throttle_data)) {
+ if (calld->retry_throttle_data != nullptr &&
+ !calld->retry_throttle_data->RecordFailure()) {
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG, "chand=%p calld=%p: retries throttled", chand, calld);
+ gpr_log(GPR_INFO, "chand=%p calld=%p: retries throttled", chand, calld);
}
return false;
}
// Check whether the call is committed.
if (calld->retry_committed) {
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG, "chand=%p calld=%p: retries already committed", chand,
+ gpr_log(GPR_INFO, "chand=%p calld=%p: retries already committed", chand,
calld);
}
return false;
@@ -1484,7 +1505,7 @@
++calld->num_attempts_completed;
if (calld->num_attempts_completed >= retry_policy->max_attempts) {
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG, "chand=%p calld=%p: exceeded %d retry attempts", chand,
+ gpr_log(GPR_INFO, "chand=%p calld=%p: exceeded %d retry attempts", chand,
calld, retry_policy->max_attempts);
}
return false;
@@ -1492,7 +1513,7 @@
// If the call was cancelled from the surface, don't retry.
if (calld->cancel_error != GRPC_ERROR_NONE) {
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"chand=%p calld=%p: call cancelled from surface, not retrying",
chand, calld);
}
@@ -1505,16 +1526,15 @@
uint32_t ms;
if (!grpc_parse_slice_to_uint32(GRPC_MDVALUE(*server_pushback_md), &ms)) {
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"chand=%p calld=%p: not retrying due to server push-back",
chand, calld);
}
return false;
} else {
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG,
- "chand=%p calld=%p: server push-back: retry in %u ms", chand,
- calld, ms);
+ gpr_log(GPR_INFO, "chand=%p calld=%p: server push-back: retry in %u ms",
+ chand, calld, ms);
}
server_pushback_ms = (grpc_millis)ms;
}
@@ -1587,7 +1607,7 @@
batch->payload->recv_initial_metadata.recv_initial_metadata_ready !=
nullptr) {
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"chand=%p calld=%p: invoking recv_initial_metadata_ready for "
"pending batch at index %" PRIuPTR,
chand, calld, i);
@@ -1623,7 +1643,7 @@
channel_data* chand = static_cast<channel_data*>(elem->channel_data);
call_data* calld = static_cast<call_data*>(elem->call_data);
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"chand=%p calld=%p: got recv_initial_metadata_ready, error=%s",
chand, calld, grpc_error_string(error));
}
@@ -1638,12 +1658,12 @@
if ((batch_data->trailing_metadata_available || error != GRPC_ERROR_NONE) &&
!retry_state->completed_recv_trailing_metadata) {
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"chand=%p calld=%p: deferring recv_initial_metadata_ready "
"(Trailers-Only)",
chand, calld);
}
- retry_state->recv_initial_metadata_ready_deferred = true;
+ retry_state->recv_initial_metadata_ready_deferred_batch = batch_data;
retry_state->recv_initial_metadata_error = GRPC_ERROR_REF(error);
if (!retry_state->started_recv_trailing_metadata) {
// recv_trailing_metadata not yet started by application; start it
@@ -1680,7 +1700,7 @@
if (batch != nullptr && batch->recv_message &&
batch->payload->recv_message.recv_message_ready != nullptr) {
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"chand=%p calld=%p: invoking recv_message_ready for "
"pending batch at index %" PRIuPTR,
chand, calld, i);
@@ -1713,7 +1733,7 @@
channel_data* chand = static_cast<channel_data*>(elem->channel_data);
call_data* calld = static_cast<call_data*>(elem->call_data);
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG, "chand=%p calld=%p: got recv_message_ready, error=%s",
+ gpr_log(GPR_INFO, "chand=%p calld=%p: got recv_message_ready, error=%s",
chand, calld, grpc_error_string(error));
}
subchannel_call_retry_state* retry_state =
@@ -1727,12 +1747,12 @@
if ((batch_data->recv_message == nullptr || error != GRPC_ERROR_NONE) &&
!retry_state->completed_recv_trailing_metadata) {
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"chand=%p calld=%p: deferring recv_message_ready (nullptr "
"message and recv_trailing_metadata pending)",
chand, calld);
}
- retry_state->recv_message_ready_deferred = true;
+ retry_state->recv_message_ready_deferred_batch = batch_data;
retry_state->recv_message_error = GRPC_ERROR_REF(error);
if (!retry_state->started_recv_trailing_metadata) {
// recv_trailing_metadata not yet started by application; start it
@@ -1751,6 +1771,59 @@
}
//
+// list of closures to execute in call combiner
+//
+
+// Represents a closure that needs to run in the call combiner as part of
+// starting or completing a batch.
+typedef struct {
+ grpc_closure* closure;
+ grpc_error* error;
+ const char* reason;
+ bool free_reason = false;
+} closure_to_execute;
+
+static void execute_closures_in_call_combiner(grpc_call_element* elem,
+ const char* caller,
+ closure_to_execute* closures,
+ size_t num_closures) {
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
+ call_data* calld = static_cast<call_data*>(elem->call_data);
+ // Note that the call combiner will be yielded for each closure that
+ // we schedule. We're already running in the call combiner, so one of
+ // the closures can be scheduled directly, but the others will
+ // have to re-enter the call combiner.
+ if (num_closures > 0) {
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_INFO, "chand=%p calld=%p: %s starting closure: %s", chand,
+ calld, caller, closures[0].reason);
+ }
+ GRPC_CLOSURE_SCHED(closures[0].closure, closures[0].error);
+ if (closures[0].free_reason) {
+ gpr_free(const_cast<char*>(closures[0].reason));
+ }
+ for (size_t i = 1; i < num_closures; ++i) {
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_INFO,
+ "chand=%p calld=%p: %s starting closure in call combiner: %s",
+ chand, calld, caller, closures[i].reason);
+ }
+ GRPC_CALL_COMBINER_START(calld->call_combiner, closures[i].closure,
+ closures[i].error, closures[i].reason);
+ if (closures[i].free_reason) {
+ gpr_free(const_cast<char*>(closures[i].reason));
+ }
+ }
+ } else {
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_INFO, "chand=%p calld=%p: no closures to run for %s", chand,
+ calld, caller);
+ }
+ GRPC_CALL_COMBINER_STOP(calld->call_combiner, "no closures to run");
+ }
+}
+
+//
// on_complete callback handling
//
@@ -1778,36 +1851,35 @@
}
}
-// Represents a closure that needs to run as a result of a completed batch.
-typedef struct {
- grpc_closure* closure;
- grpc_error* error;
- const char* reason;
-} closure_to_execute;
-
// Adds any necessary closures for deferred recv_initial_metadata and
// recv_message callbacks to closures, updating *num_closures as needed.
static void add_closures_for_deferred_recv_callbacks(
subchannel_batch_data* batch_data, subchannel_call_retry_state* retry_state,
closure_to_execute* closures, size_t* num_closures) {
- if (batch_data->batch.recv_trailing_metadata &&
- retry_state->recv_initial_metadata_ready_deferred) {
- closure_to_execute* closure = &closures[(*num_closures)++];
- closure->closure =
- GRPC_CLOSURE_INIT(&batch_data->recv_initial_metadata_ready,
- invoke_recv_initial_metadata_callback, batch_data,
- grpc_schedule_on_exec_ctx);
- closure->error = retry_state->recv_initial_metadata_error;
- closure->reason = "resuming recv_initial_metadata_ready";
- }
- if (batch_data->batch.recv_trailing_metadata &&
- retry_state->recv_message_ready_deferred) {
- closure_to_execute* closure = &closures[(*num_closures)++];
- closure->closure = GRPC_CLOSURE_INIT(&batch_data->recv_message_ready,
- invoke_recv_message_callback,
- batch_data, grpc_schedule_on_exec_ctx);
- closure->error = retry_state->recv_message_error;
- closure->reason = "resuming recv_message_ready";
+ if (batch_data->batch.recv_trailing_metadata) {
+ // Add closure for deferred recv_initial_metadata_ready.
+ if (retry_state->recv_initial_metadata_ready_deferred_batch != nullptr) {
+ closure_to_execute* closure = &closures[(*num_closures)++];
+ closure->closure = GRPC_CLOSURE_INIT(
+ &batch_data->recv_initial_metadata_ready,
+ invoke_recv_initial_metadata_callback,
+ retry_state->recv_initial_metadata_ready_deferred_batch,
+ grpc_schedule_on_exec_ctx);
+ closure->error = retry_state->recv_initial_metadata_error;
+ closure->reason = "resuming recv_initial_metadata_ready";
+ retry_state->recv_initial_metadata_ready_deferred_batch = nullptr;
+ }
+ // Add closure for deferred recv_message_ready.
+ if (retry_state->recv_message_ready_deferred_batch != nullptr) {
+ closure_to_execute* closure = &closures[(*num_closures)++];
+ closure->closure = GRPC_CLOSURE_INIT(
+ &batch_data->recv_message_ready, invoke_recv_message_callback,
+ retry_state->recv_message_ready_deferred_batch,
+ grpc_schedule_on_exec_ctx);
+ closure->error = retry_state->recv_message_error;
+ closure->reason = "resuming recv_message_ready";
+ retry_state->recv_message_ready_deferred_batch = nullptr;
+ }
}
}
@@ -1821,7 +1893,7 @@
channel_data* chand = static_cast<channel_data*>(elem->channel_data);
call_data* calld = static_cast<call_data*>(elem->call_data);
bool have_pending_send_message_ops =
- retry_state->started_send_message_count < calld->send_messages.size();
+ retry_state->started_send_message_count < calld->send_messages->size();
bool have_pending_send_trailing_metadata_op =
calld->seen_send_trailing_metadata &&
!retry_state->started_send_trailing_metadata;
@@ -1839,7 +1911,7 @@
}
if (have_pending_send_message_ops || have_pending_send_trailing_metadata_op) {
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"chand=%p calld=%p: starting next batch for pending send op(s)",
chand, calld);
}
@@ -1864,7 +1936,7 @@
pending_batch* pending = &calld->pending_batches[i];
if (pending_batch_is_completed(pending, calld, retry_state)) {
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"chand=%p calld=%p: pending batch completed at index %" PRIuPTR,
chand, calld, i);
}
@@ -1897,7 +1969,7 @@
pending_batch* pending = &calld->pending_batches[i];
if (pending_batch_is_unstarted(pending, calld, retry_state)) {
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"chand=%p calld=%p: failing unstarted pending batch at index "
"%" PRIuPTR,
chand, calld, i);
@@ -1941,7 +2013,7 @@
call_data* calld = static_cast<call_data*>(elem->call_data);
if (grpc_client_channel_trace.enabled()) {
char* batch_str = grpc_transport_stream_op_batch_string(&batch_data->batch);
- gpr_log(GPR_DEBUG, "chand=%p calld=%p: got on_complete, error=%s, batch=%s",
+ gpr_log(GPR_INFO, "chand=%p calld=%p: got on_complete, error=%s, batch=%s",
chand, calld, grpc_error_string(error), batch_str);
gpr_free(batch_str);
}
@@ -1952,11 +2024,13 @@
// If we have previously completed recv_trailing_metadata, then the
// call is finished.
bool call_finished = retry_state->completed_recv_trailing_metadata;
+ // Record whether we were already committed before receiving this callback.
+ const bool previously_committed = calld->retry_committed;
// Update bookkeeping in retry_state.
update_retry_state_for_completed_batch(batch_data, retry_state);
if (call_finished) {
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG, "chand=%p calld=%p: call already finished", chand,
+ gpr_log(GPR_INFO, "chand=%p calld=%p: call already finished", chand,
calld);
}
} else {
@@ -1980,35 +2054,39 @@
if (md_batch->idx.named.grpc_retry_pushback_ms != nullptr) {
server_pushback_md = &md_batch->idx.named.grpc_retry_pushback_ms->md;
}
- } else if (retry_state->completed_recv_trailing_metadata) {
- call_finished = true;
}
- if (call_finished && grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG, "chand=%p calld=%p: call finished, status=%s", chand,
- calld, grpc_status_code_to_string(status));
- }
- // If the call is finished, check if we should retry.
- if (call_finished &&
- maybe_retry(elem, batch_data, status, server_pushback_md)) {
- // Unref batch_data for deferred recv_initial_metadata_ready or
- // recv_message_ready callbacks, if any.
- if (batch_data->batch.recv_trailing_metadata &&
- retry_state->recv_initial_metadata_ready_deferred) {
- batch_data_unref(batch_data);
- GRPC_ERROR_UNREF(retry_state->recv_initial_metadata_error);
+ // If the call just finished, check if we should retry.
+ if (call_finished) {
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_INFO, "chand=%p calld=%p: call finished, status=%s", chand,
+ calld, grpc_status_code_to_string(status));
}
- if (batch_data->batch.recv_trailing_metadata &&
- retry_state->recv_message_ready_deferred) {
+ if (maybe_retry(elem, batch_data, status, server_pushback_md)) {
+ // Unref batch_data for deferred recv_initial_metadata_ready or
+ // recv_message_ready callbacks, if any.
+ if (batch_data->batch.recv_trailing_metadata &&
+ retry_state->recv_initial_metadata_ready_deferred_batch !=
+ nullptr) {
+ batch_data_unref(batch_data);
+ GRPC_ERROR_UNREF(retry_state->recv_initial_metadata_error);
+ }
+ if (batch_data->batch.recv_trailing_metadata &&
+ retry_state->recv_message_ready_deferred_batch != nullptr) {
+ batch_data_unref(batch_data);
+ GRPC_ERROR_UNREF(retry_state->recv_message_error);
+ }
batch_data_unref(batch_data);
- GRPC_ERROR_UNREF(retry_state->recv_message_error);
+ return;
}
- batch_data_unref(batch_data);
- return;
+ // Not retrying, so commit the call.
+ retry_commit(elem, retry_state);
}
}
- // If the call is finished or retries are committed, free cached data for
- // send ops that we've just completed.
- if (call_finished || calld->retry_committed) {
+ // If we were already committed before receiving this callback, free
+ // cached data for send ops that we've just completed. (If the call has
+ // just now finished, the call to retry_commit() above will have freed all
+ // cached send ops, so we don't need to do it here.)
+ if (previously_committed) {
free_cached_send_op_data_for_completed_batch(elem, batch_data, retry_state);
}
// Call not being retried.
@@ -2043,20 +2121,8 @@
// Don't need batch_data anymore.
batch_data_unref(batch_data);
// Schedule all of the closures identified above.
- // Note that the call combiner will be yielded for each closure that
- // we schedule. We're already running in the call combiner, so one of
- // the closures can be scheduled directly, but the others will
- // have to re-enter the call combiner.
- if (num_closures > 0) {
- GRPC_CLOSURE_SCHED(closures[0].closure, closures[0].error);
- for (size_t i = 1; i < num_closures; ++i) {
- GRPC_CALL_COMBINER_START(calld->call_combiner, closures[i].closure,
- closures[i].error, closures[i].reason);
- }
- } else {
- GRPC_CALL_COMBINER_STOP(calld->call_combiner,
- "no closures to run for on_complete");
- }
+ execute_closures_in_call_combiner(elem, "on_complete", closures,
+ num_closures);
}
//
@@ -2073,6 +2139,31 @@
grpc_subchannel_call_process_op(subchannel_call, batch);
}
+// Adds a closure to closures that will execute batch in the call combiner.
+static void add_closure_for_subchannel_batch(
+ call_data* calld, grpc_transport_stream_op_batch* batch,
+ closure_to_execute* closures, size_t* num_closures) {
+ batch->handler_private.extra_arg = calld->subchannel_call;
+ GRPC_CLOSURE_INIT(&batch->handler_private.closure,
+ start_batch_in_call_combiner, batch,
+ grpc_schedule_on_exec_ctx);
+ closure_to_execute* closure = &closures[(*num_closures)++];
+ closure->closure = &batch->handler_private.closure;
+ closure->error = GRPC_ERROR_NONE;
+ // If the tracer is enabled, we log a more detailed message, which
+ // requires dynamic allocation. This will be freed in
+ // start_retriable_subchannel_batches().
+ if (grpc_client_channel_trace.enabled()) {
+ char* batch_str = grpc_transport_stream_op_batch_string(batch);
+ gpr_asprintf(const_cast<char**>(&closure->reason),
+ "starting batch in call combiner: %s", batch_str);
+ gpr_free(batch_str);
+ closure->free_reason = true;
+ } else {
+ closure->reason = "start_subchannel_batch";
+ }
+}
+
// Adds retriable send_initial_metadata op to batch_data.
static void add_retriable_send_initial_metadata_op(
call_data* calld, subchannel_call_retry_state* retry_state,
@@ -2132,12 +2223,12 @@
channel_data* chand = static_cast<channel_data*>(elem->channel_data);
call_data* calld = static_cast<call_data*>(elem->call_data);
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"chand=%p calld=%p: starting calld->send_messages[%" PRIuPTR "]",
chand, calld, retry_state->started_send_message_count);
}
grpc_core::ByteStreamCache* cache =
- calld->send_messages[retry_state->started_send_message_count];
+ (*calld->send_messages)[retry_state->started_send_message_count];
++retry_state->started_send_message_count;
batch_data->send_message.Init(cache);
batch_data->batch.send_message = true;
@@ -2219,7 +2310,7 @@
channel_data* chand = static_cast<channel_data*>(elem->channel_data);
call_data* calld = static_cast<call_data*>(elem->call_data);
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"chand=%p calld=%p: call failed but recv_trailing_metadata not "
"started; starting it internally",
chand, calld);
@@ -2228,8 +2319,12 @@
static_cast<subchannel_call_retry_state*>(
grpc_connected_subchannel_call_get_parent_data(
calld->subchannel_call));
- subchannel_batch_data* batch_data = batch_data_create(elem, 1);
+ // Create batch_data with 2 refs, since this batch will be unreffed twice:
+ // once when the subchannel batch returns, and again when we actually get
+ // a recv_trailing_metadata op from the surface.
+ subchannel_batch_data* batch_data = batch_data_create(elem, 2);
add_retriable_recv_trailing_metadata_op(calld, retry_state, batch_data);
+ retry_state->recv_trailing_metadata_internal_batch = batch_data;
// Note: This will release the call combiner.
grpc_subchannel_call_process_op(calld->subchannel_call, &batch_data->batch);
}
@@ -2247,7 +2342,7 @@
!retry_state->started_send_initial_metadata &&
!calld->pending_send_initial_metadata) {
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"chand=%p calld=%p: replaying previously completed "
"send_initial_metadata op",
chand, calld);
@@ -2258,12 +2353,12 @@
}
// send_message.
// Note that we can only have one send_message op in flight at a time.
- if (retry_state->started_send_message_count < calld->send_messages.size() &&
+ if (retry_state->started_send_message_count < calld->send_messages->size() &&
retry_state->started_send_message_count ==
retry_state->completed_send_message_count &&
!calld->pending_send_message) {
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"chand=%p calld=%p: replaying previously completed "
"send_message op",
chand, calld);
@@ -2278,11 +2373,11 @@
// to start, since we can't send down any more send_message ops after
// send_trailing_metadata.
if (calld->seen_send_trailing_metadata &&
- retry_state->started_send_message_count == calld->send_messages.size() &&
+ retry_state->started_send_message_count == calld->send_messages->size() &&
!retry_state->started_send_trailing_metadata &&
!calld->pending_send_trailing_metadata) {
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"chand=%p calld=%p: replaying previously completed "
"send_trailing_metadata op",
chand, calld);
@@ -2300,7 +2395,7 @@
// *num_batches as needed.
static void add_subchannel_batches_for_pending_batches(
grpc_call_element* elem, subchannel_call_retry_state* retry_state,
- grpc_transport_stream_op_batch** batches, size_t* num_batches) {
+ closure_to_execute* closures, size_t* num_closures) {
call_data* calld = static_cast<call_data*>(elem->call_data);
for (size_t i = 0; i < GPR_ARRAY_SIZE(calld->pending_batches); ++i) {
pending_batch* pending = &calld->pending_batches[i];
@@ -2329,7 +2424,7 @@
// send_message ops after send_trailing_metadata.
if (batch->send_trailing_metadata &&
(retry_state->started_send_message_count + batch->send_message <
- calld->send_messages.size() ||
+ calld->send_messages->size() ||
retry_state->started_send_trailing_metadata)) {
continue;
}
@@ -2343,13 +2438,37 @@
}
if (batch->recv_trailing_metadata &&
retry_state->started_recv_trailing_metadata) {
+ // If we previously completed a recv_trailing_metadata op
+ // initiated by start_internal_recv_trailing_metadata(), use the
+ // result of that instead of trying to re-start this op.
+ if (retry_state->recv_trailing_metadata_internal_batch != nullptr) {
+ // If the batch completed, then trigger the completion callback
+ // directly, so that we return the previously returned results to
+ // the application. Otherwise, just unref the internally
+ // started subchannel batch, since we'll propagate the
+ // completion when it completes.
+ if (retry_state->completed_recv_trailing_metadata) {
+ subchannel_batch_data* batch_data =
+ retry_state->recv_trailing_metadata_internal_batch;
+ closure_to_execute* closure = &closures[(*num_closures)++];
+ closure->closure = &batch_data->on_complete;
+ // Batches containing recv_trailing_metadata always succeed.
+ closure->error = GRPC_ERROR_NONE;
+ closure->reason =
+ "re-executing on_complete for recv_trailing_metadata "
+ "to propagate internally triggered result";
+ } else {
+ batch_data_unref(retry_state->recv_trailing_metadata_internal_batch);
+ }
+ retry_state->recv_trailing_metadata_internal_batch = nullptr;
+ }
continue;
}
// If we're not retrying, just send the batch as-is.
if (calld->method_params == nullptr ||
calld->method_params->retry_policy() == nullptr ||
calld->retry_committed) {
- batches[(*num_batches)++] = batch;
+ add_closure_for_subchannel_batch(calld, batch, closures, num_closures);
pending_batch_clear(calld, pending);
continue;
}
@@ -2386,7 +2505,8 @@
GPR_ASSERT(batch->collect_stats);
add_retriable_recv_trailing_metadata_op(calld, retry_state, batch_data);
}
- batches[(*num_batches)++] = &batch_data->batch;
+ add_closure_for_subchannel_batch(calld, &batch_data->batch, closures,
+ num_closures);
}
}
@@ -2397,69 +2517,36 @@
channel_data* chand = static_cast<channel_data*>(elem->channel_data);
call_data* calld = static_cast<call_data*>(elem->call_data);
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG, "chand=%p calld=%p: constructing retriable batches",
+ gpr_log(GPR_INFO, "chand=%p calld=%p: constructing retriable batches",
chand, calld);
}
subchannel_call_retry_state* retry_state =
static_cast<subchannel_call_retry_state*>(
grpc_connected_subchannel_call_get_parent_data(
calld->subchannel_call));
+ // Construct list of closures to execute, one for each pending batch.
// We can start up to 6 batches.
- grpc_transport_stream_op_batch*
- batches[GPR_ARRAY_SIZE(calld->pending_batches)];
- size_t num_batches = 0;
+ closure_to_execute closures[GPR_ARRAY_SIZE(calld->pending_batches)];
+ size_t num_closures = 0;
// Replay previously-returned send_* ops if needed.
subchannel_batch_data* replay_batch_data =
maybe_create_subchannel_batch_for_replay(elem, retry_state);
if (replay_batch_data != nullptr) {
- batches[num_batches++] = &replay_batch_data->batch;
+ add_closure_for_subchannel_batch(calld, &replay_batch_data->batch, closures,
+ &num_closures);
}
// Now add pending batches.
- add_subchannel_batches_for_pending_batches(elem, retry_state, batches,
- &num_batches);
+ add_subchannel_batches_for_pending_batches(elem, retry_state, closures,
+ &num_closures);
// Start batches on subchannel call.
- // Note that the call combiner will be yielded for each batch that we
- // send down. We're already running in the call combiner, so one of
- // the batches can be started directly, but the others will have to
- // re-enter the call combiner.
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"chand=%p calld=%p: starting %" PRIuPTR
" retriable batches on subchannel_call=%p",
- chand, calld, num_batches, calld->subchannel_call);
+ chand, calld, num_closures, calld->subchannel_call);
}
- if (num_batches == 0) {
- // This should be fairly rare, but it can happen when (e.g.) an
- // attempt completes before it has finished replaying all
- // previously sent messages.
- GRPC_CALL_COMBINER_STOP(calld->call_combiner,
- "no retriable subchannel batches to start");
- } else {
- for (size_t i = 1; i < num_batches; ++i) {
- if (grpc_client_channel_trace.enabled()) {
- char* batch_str = grpc_transport_stream_op_batch_string(batches[i]);
- gpr_log(GPR_DEBUG,
- "chand=%p calld=%p: starting batch in call combiner: %s", chand,
- calld, batch_str);
- gpr_free(batch_str);
- }
- batches[i]->handler_private.extra_arg = calld->subchannel_call;
- GRPC_CLOSURE_INIT(&batches[i]->handler_private.closure,
- start_batch_in_call_combiner, batches[i],
- grpc_schedule_on_exec_ctx);
- GRPC_CALL_COMBINER_START(calld->call_combiner,
- &batches[i]->handler_private.closure,
- GRPC_ERROR_NONE, "start_subchannel_batch");
- }
- if (grpc_client_channel_trace.enabled()) {
- char* batch_str = grpc_transport_stream_op_batch_string(batches[0]);
- gpr_log(GPR_DEBUG, "chand=%p calld=%p: starting batch: %s", chand, calld,
- batch_str);
- gpr_free(batch_str);
- }
- // Note: This will release the call combiner.
- grpc_subchannel_call_process_op(calld->subchannel_call, batches[0]);
- }
+ execute_closures_in_call_combiner(elem, "start_retriable_subchannel_batches",
+ closures, num_closures);
}
//
@@ -2484,7 +2571,7 @@
grpc_error* new_error = calld->pick.connected_subchannel->CreateCall(
call_args, &calld->subchannel_call);
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG, "chand=%p calld=%p: create subchannel_call=%p: error=%s",
+ gpr_log(GPR_INFO, "chand=%p calld=%p: create subchannel_call=%p: error=%s",
chand, calld, calld->subchannel_call, grpc_error_string(new_error));
}
if (new_error != GRPC_ERROR_NONE) {
@@ -2525,7 +2612,7 @@
: GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
"Failed to create subchannel", &error, 1);
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"chand=%p calld=%p: failed to create subchannel: error=%s",
chand, calld, grpc_error_string(new_error));
}
@@ -2569,7 +2656,7 @@
// the one we started it on. However, this will just be a no-op.
if (error != GRPC_ERROR_NONE && chand->lb_policy != nullptr) {
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG, "chand=%p calld=%p: cancelling pick from LB policy %p",
+ gpr_log(GPR_INFO, "chand=%p calld=%p: cancelling pick from LB policy %p",
chand, calld, chand->lb_policy.get());
}
chand->lb_policy->CancelPickLocked(&calld->pick, GRPC_ERROR_REF(error));
@@ -2584,8 +2671,8 @@
channel_data* chand = static_cast<channel_data*>(elem->channel_data);
call_data* calld = static_cast<call_data*>(elem->call_data);
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG, "chand=%p calld=%p: pick completed asynchronously",
- chand, calld);
+ gpr_log(GPR_INFO, "chand=%p calld=%p: pick completed asynchronously", chand,
+ calld);
}
async_pick_done_locked(elem, GRPC_ERROR_REF(error));
GRPC_CALL_STACK_UNREF(calld->owning_call, "pick_callback");
@@ -2597,12 +2684,11 @@
channel_data* chand = static_cast<channel_data*>(elem->channel_data);
call_data* calld = static_cast<call_data*>(elem->call_data);
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG, "chand=%p calld=%p: applying service config to call",
+ gpr_log(GPR_INFO, "chand=%p calld=%p: applying service config to call",
chand, calld);
}
if (chand->retry_throttle_data != nullptr) {
- calld->retry_throttle_data =
- grpc_server_retry_throttle_data_ref(chand->retry_throttle_data);
+ calld->retry_throttle_data = chand->retry_throttle_data->Ref();
}
if (chand->method_params_table != nullptr) {
calld->method_params = grpc_core::ServiceConfig::MethodConfigTableLookup(
@@ -2636,8 +2722,8 @@
channel_data* chand = static_cast<channel_data*>(elem->channel_data);
call_data* calld = static_cast<call_data*>(elem->call_data);
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG, "chand=%p calld=%p: starting pick on lb_policy=%p",
- chand, calld, chand->lb_policy.get());
+ gpr_log(GPR_INFO, "chand=%p calld=%p: starting pick on lb_policy=%p", chand,
+ calld, chand->lb_policy.get());
}
// Only get service config data on the first attempt.
if (calld->num_attempts_completed == 0) {
@@ -2684,7 +2770,7 @@
if (pick_done) {
// Pick completed synchronously.
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG, "chand=%p calld=%p: pick completed synchronously",
+ gpr_log(GPR_INFO, "chand=%p calld=%p: pick completed synchronously",
chand, calld);
}
GRPC_CALL_STACK_UNREF(calld->owning_call, "pick_callback");
@@ -2728,7 +2814,7 @@
channel_data* chand = static_cast<channel_data*>(elem->channel_data);
call_data* calld = static_cast<call_data*>(elem->call_data);
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"chand=%p calld=%p: cancelling pick waiting for resolver result",
chand, calld);
}
@@ -2748,7 +2834,7 @@
if (args->finished) {
/* cancelled, do nothing */
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG, "call cancelled before resolver result");
+ gpr_log(GPR_INFO, "call cancelled before resolver result");
}
gpr_free(args);
return;
@@ -2759,14 +2845,14 @@
call_data* calld = static_cast<call_data*>(elem->call_data);
if (error != GRPC_ERROR_NONE) {
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG, "chand=%p calld=%p: resolver failed to return data",
+ gpr_log(GPR_INFO, "chand=%p calld=%p: resolver failed to return data",
chand, calld);
}
async_pick_done_locked(elem, GRPC_ERROR_REF(error));
} else if (chand->resolver == nullptr) {
// Shutting down.
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG, "chand=%p calld=%p: resolver disconnected", chand,
+ gpr_log(GPR_INFO, "chand=%p calld=%p: resolver disconnected", chand,
calld);
}
async_pick_done_locked(
@@ -2782,7 +2868,7 @@
.send_initial_metadata_flags;
if (send_initial_metadata_flags & GRPC_INITIAL_METADATA_WAIT_FOR_READY) {
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"chand=%p calld=%p: resolver returned but no LB policy; "
"wait_for_ready=true; trying again",
chand, calld);
@@ -2790,7 +2876,7 @@
pick_after_resolver_result_start_locked(elem);
} else {
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"chand=%p calld=%p: resolver returned but no LB policy; "
"wait_for_ready=false; failing",
chand, calld);
@@ -2803,7 +2889,7 @@
}
} else {
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG, "chand=%p calld=%p: resolver returned, doing pick",
+ gpr_log(GPR_INFO, "chand=%p calld=%p: resolver returned, doing pick",
chand, calld);
}
if (pick_callback_start_locked(elem)) {
@@ -2821,7 +2907,7 @@
channel_data* chand = static_cast<channel_data*>(elem->channel_data);
call_data* calld = static_cast<call_data*>(elem->call_data);
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"chand=%p calld=%p: deferring pick pending resolver result", chand,
calld);
}
@@ -2888,7 +2974,7 @@
// If we've previously been cancelled, immediately fail any new batches.
if (calld->cancel_error != GRPC_ERROR_NONE) {
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG, "chand=%p calld=%p: failing batch with error: %s",
+ gpr_log(GPR_INFO, "chand=%p calld=%p: failing batch with error: %s",
chand, calld, grpc_error_string(calld->cancel_error));
}
// Note: This will release the call combiner.
@@ -2907,7 +2993,7 @@
calld->cancel_error =
GRPC_ERROR_REF(batch->payload->cancel_stream.cancel_error);
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG, "chand=%p calld=%p: recording cancel_error=%s", chand,
+ gpr_log(GPR_INFO, "chand=%p calld=%p: recording cancel_error=%s", chand,
calld, grpc_error_string(calld->cancel_error));
}
// If we do not have a subchannel call (i.e., a pick has not yet
@@ -2933,7 +3019,7 @@
// streaming calls).
if (calld->subchannel_call != nullptr) {
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"chand=%p calld=%p: starting batch on subchannel_call=%p", chand,
calld, calld->subchannel_call);
}
@@ -2945,7 +3031,7 @@
// combiner to start a pick.
if (batch->send_initial_metadata) {
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG, "chand=%p calld=%p: entering client_channel combiner",
+ gpr_log(GPR_INFO, "chand=%p calld=%p: entering client_channel combiner",
chand, calld);
}
GRPC_CLOSURE_SCHED(
@@ -2955,7 +3041,7 @@
} else {
// For all other batches, release the call combiner.
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"chand=%p calld=%p: saved batch, yeilding call combiner", chand,
calld);
}
@@ -2981,6 +3067,7 @@
calld->deadline);
}
calld->enable_retries = chand->enable_retries;
+ calld->send_messages.Init();
return GRPC_ERROR_NONE;
}
@@ -2994,6 +3081,7 @@
grpc_deadline_state_destroy(elem);
}
grpc_slice_unref_internal(calld->path);
+ calld->retry_throttle_data.reset();
calld->method_params.reset();
GRPC_ERROR_UNREF(calld->cancel_error);
if (calld->subchannel_call != nullptr) {
@@ -3015,6 +3103,7 @@
calld->pick.subchannel_call_context[i].value);
}
}
+ calld->send_messages.Destroy();
GRPC_CLOSURE_SCHED(then_schedule_closure, GRPC_ERROR_NONE);
}
@@ -3163,6 +3252,8 @@
external_connectivity_watcher* found = nullptr;
if (w->state != nullptr) {
external_connectivity_watcher_list_append(w->chand, w);
+ // An assumption is being made that the closure is scheduled on the exec ctx
+ // scheduler and that GRPC_CLOSURE_RUN would run the closure immediately.
GRPC_CLOSURE_RUN(w->watcher_timer_init, GRPC_ERROR_NONE);
GRPC_CLOSURE_INIT(&w->my_closure, on_external_watch_complete_locked, w,
grpc_combiner_scheduler(w->chand->combiner));
diff --git a/src/core/ext/filters/client_channel/client_channel_plugin.cc b/src/core/ext/filters/client_channel/client_channel_plugin.cc
index 3c3a975..8385852 100644
--- a/src/core/ext/filters/client_channel/client_channel_plugin.cc
+++ b/src/core/ext/filters/client_channel/client_channel_plugin.cc
@@ -39,38 +39,13 @@
builder, static_cast<const grpc_channel_filter*>(arg), nullptr, nullptr);
}
-static bool set_default_host_if_unset(grpc_channel_stack_builder* builder,
- void* unused) {
- const grpc_channel_args* args =
- grpc_channel_stack_builder_get_channel_arguments(builder);
- for (size_t i = 0; i < args->num_args; i++) {
- if (0 == strcmp(args->args[i].key, GRPC_ARG_DEFAULT_AUTHORITY) ||
- 0 == strcmp(args->args[i].key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG)) {
- return true;
- }
- }
- grpc_core::UniquePtr<char> default_authority =
- grpc_core::ResolverRegistry::GetDefaultAuthority(
- grpc_channel_stack_builder_get_target(builder));
- if (default_authority.get() != nullptr) {
- grpc_arg arg = grpc_channel_arg_string_create(
- (char*)GRPC_ARG_DEFAULT_AUTHORITY, default_authority.get());
- grpc_channel_args* new_args = grpc_channel_args_copy_and_add(args, &arg, 1);
- grpc_channel_stack_builder_set_channel_arguments(builder, new_args);
- grpc_channel_args_destroy(new_args);
- }
- return true;
-}
-
void grpc_client_channel_init(void) {
grpc_core::LoadBalancingPolicyRegistry::Builder::InitRegistry();
grpc_core::ResolverRegistry::Builder::InitRegistry();
- grpc_retry_throttle_map_init();
+ grpc_core::internal::ServerRetryThrottleMap::Init();
grpc_proxy_mapper_registry_init();
grpc_register_http_proxy_mapper();
grpc_subchannel_index_init();
- grpc_channel_init_register_stage(GRPC_CLIENT_CHANNEL, INT_MIN,
- set_default_host_if_unset, nullptr);
grpc_channel_init_register_stage(
GRPC_CLIENT_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, append_filter,
(void*)&grpc_client_channel_filter);
@@ -81,7 +56,7 @@
grpc_subchannel_index_shutdown();
grpc_channel_init_shutdown();
grpc_proxy_mapper_registry_shutdown();
- grpc_retry_throttle_map_shutdown();
+ grpc_core::internal::ServerRetryThrottleMap::Shutdown();
grpc_core::ResolverRegistry::Builder::ShutdownRegistry();
grpc_core::LoadBalancingPolicyRegistry::Builder::ShutdownRegistry();
}
diff --git a/src/core/ext/filters/client_channel/http_connect_handshaker.cc b/src/core/ext/filters/client_channel/http_connect_handshaker.cc
index fb29fa7..4e8b8b7 100644
--- a/src/core/ext/filters/client_channel/http_connect_handshaker.cc
+++ b/src/core/ext/filters/client_channel/http_connect_handshaker.cc
@@ -326,7 +326,7 @@
static const grpc_handshaker_vtable http_connect_handshaker_vtable = {
http_connect_handshaker_destroy, http_connect_handshaker_shutdown,
- http_connect_handshaker_do_handshake};
+ http_connect_handshaker_do_handshake, "http_connect"};
static grpc_handshaker* grpc_http_connect_handshaker_create() {
http_connect_handshaker* handshaker =
diff --git a/src/core/ext/filters/client_channel/lb_policy.cc b/src/core/ext/filters/client_channel/lb_policy.cc
index fa63dd7..e065f45 100644
--- a/src/core/ext/filters/client_channel/lb_policy.cc
+++ b/src/core/ext/filters/client_channel/lb_policy.cc
@@ -44,13 +44,13 @@
GRPC_CLOSURE_SCHED(request_reresolution_, error);
request_reresolution_ = nullptr;
if (grpc_lb_trace->enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"%s %p: scheduling re-resolution closure with error=%s.",
grpc_lb_trace->name(), this, grpc_error_string(error));
}
} else {
if (grpc_lb_trace->enabled()) {
- gpr_log(GPR_DEBUG, "%s %p: no available re-resolution closure.",
+ gpr_log(GPR_INFO, "%s %p: no available re-resolution closure.",
grpc_lb_trace->name(), this);
}
}
diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h
index c3e43e5..454e00a 100644
--- a/src/core/ext/filters/client_channel/lb_policy.h
+++ b/src/core/ext/filters/client_channel/lb_policy.h
@@ -162,6 +162,10 @@
GRPC_ABSTRACT_BASE_CLASS
protected:
+ // So Delete() can access our protected dtor.
+ template <typename T>
+ friend void Delete(T*);
+
explicit LoadBalancingPolicy(const Args& args);
virtual ~LoadBalancingPolicy();
diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc
index e805593..70a91b2 100644
--- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc
+++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc
@@ -76,6 +76,7 @@
#include "src/core/ext/filters/client_channel/client_channel.h"
#include "src/core/ext/filters/client_channel/client_channel_factory.h"
#include "src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h"
+#include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h"
#include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h"
#include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h"
#include "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h"
@@ -189,6 +190,10 @@
bool seen_initial_response() const { return seen_initial_response_; }
private:
+ // So Delete() can access our private dtor.
+ template <typename T>
+ friend void grpc_core::Delete(T*);
+
~BalancerCallState();
GrpcLb* grpclb_policy() const {
@@ -505,9 +510,7 @@
// the polling entities from client_channel.
GPR_ASSERT(grpclb_policy()->server_name_ != nullptr);
GPR_ASSERT(grpclb_policy()->server_name_[0] != '\0');
- grpc_slice host =
- grpc_slice_from_copied_string(grpclb_policy()->server_name_);
- grpc_millis deadline =
+ const grpc_millis deadline =
grpclb_policy()->lb_call_timeout_ms_ == 0
? GRPC_MILLIS_INF_FUTURE
: ExecCtx::Get()->Now() + grpclb_policy()->lb_call_timeout_ms_;
@@ -515,8 +518,7 @@
grpclb_policy()->lb_channel_, nullptr, GRPC_PROPAGATE_DEFAULTS,
grpclb_policy_->interested_parties(),
GRPC_MDSTR_SLASH_GRPC_DOT_LB_DOT_V1_DOT_LOADBALANCER_SLASH_BALANCELOAD,
- &host, deadline, nullptr);
- grpc_slice_unref_internal(host);
+ nullptr, deadline, nullptr);
// Init the LB call request payload.
grpc_grpclb_request* request =
grpc_grpclb_request_create(grpclb_policy()->server_name_);
@@ -983,6 +985,14 @@
// with the one from the grpclb policy, used to propagate updates to
// the LB channel.
GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR,
+ // The LB channel should use the authority indicated by the target
+ // authority table (see \a grpc_lb_policy_grpclb_modify_lb_channel_args),
+ // as opposed to the authority from the parent channel.
+ GRPC_ARG_DEFAULT_AUTHORITY,
+ // Just as for \a GRPC_ARG_DEFAULT_AUTHORITY, the LB channel should be
+ // treated as a stand-alone channel and not inherit this argument from the
+ // args of the parent channel.
+ GRPC_SSL_TARGET_NAME_OVERRIDE_ARG,
};
// Channel args to add.
const grpc_arg args_to_add[] = {
@@ -994,6 +1004,9 @@
// address updates into the LB channel.
grpc_core::FakeResolverResponseGenerator::MakeChannelArg(
response_generator),
+ // A channel arg indicating the target is a grpclb load balancer.
+ grpc_channel_arg_integer_create(
+ const_cast<char*>(GRPC_ARG_ADDRESS_IS_GRPCLB_LOAD_BALANCER), 1),
};
// Construct channel args.
grpc_channel_args* new_args = grpc_channel_args_copy_and_add_and_remove(
@@ -1238,7 +1251,7 @@
}
} else { // rr_policy_ == NULL
if (grpc_lb_glb_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"[grpclb %p] No RR policy. Adding to grpclb's pending picks",
this);
}
@@ -1404,14 +1417,13 @@
void GrpcLb::StartBalancerCallRetryTimerLocked() {
grpc_millis next_try = lb_call_backoff_.NextAttemptTime();
if (grpc_lb_glb_trace.enabled()) {
- gpr_log(GPR_DEBUG, "[grpclb %p] Connection to LB server lost...", this);
+ gpr_log(GPR_INFO, "[grpclb %p] Connection to LB server lost...", this);
grpc_millis timeout = next_try - ExecCtx::Get()->Now();
if (timeout > 0) {
- gpr_log(GPR_DEBUG,
- "[grpclb %p] ... retry_timer_active in %" PRIuPTR "ms.", this,
- timeout);
+ gpr_log(GPR_INFO, "[grpclb %p] ... retry_timer_active in %" PRIuPTR "ms.",
+ this, timeout);
} else {
- gpr_log(GPR_DEBUG, "[grpclb %p] ... retry_timer_active immediately.",
+ gpr_log(GPR_INFO, "[grpclb %p] ... retry_timer_active immediately.",
this);
}
}
@@ -1690,9 +1702,11 @@
grpc_channel_args* GrpcLb::CreateRoundRobinPolicyArgsLocked() {
grpc_lb_addresses* addresses;
+ bool is_backend_from_grpclb_load_balancer = false;
if (serverlist_ != nullptr) {
GPR_ASSERT(serverlist_->num_servers > 0);
addresses = ProcessServerlist(serverlist_);
+ is_backend_from_grpclb_load_balancer = true;
} else {
// If CreateOrUpdateRoundRobinPolicyLocked() is invoked when we haven't
// received any serverlist from the balancer, we use the fallback backends
@@ -1706,9 +1720,18 @@
// Replace the LB addresses in the channel args that we pass down to
// the subchannel.
static const char* keys_to_remove[] = {GRPC_ARG_LB_ADDRESSES};
- const grpc_arg arg = grpc_lb_addresses_create_channel_arg(addresses);
+ const grpc_arg args_to_add[] = {
+ grpc_lb_addresses_create_channel_arg(addresses),
+ // A channel arg indicating if the target is a backend inferred from a
+ // grpclb load balancer.
+ grpc_channel_arg_integer_create(
+ const_cast<char*>(
+ GRPC_ARG_ADDRESS_IS_BACKEND_FROM_GRPCLB_LOAD_BALANCER),
+ is_backend_from_grpclb_load_balancer),
+ };
grpc_channel_args* args = grpc_channel_args_copy_and_add_and_remove(
- args_, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), &arg, 1);
+ args_, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), args_to_add,
+ GPR_ARRAY_SIZE(args_to_add));
grpc_lb_addresses_destroy(addresses);
return args;
}
@@ -1719,7 +1742,7 @@
GPR_ASSERT(args != nullptr);
if (rr_policy_ != nullptr) {
if (grpc_lb_glb_trace.enabled()) {
- gpr_log(GPR_DEBUG, "[grpclb %p] Updating RR policy %p", this,
+ gpr_log(GPR_INFO, "[grpclb %p] Updating RR policy %p", this,
rr_policy_.get());
}
rr_policy_->UpdateLocked(*args);
@@ -1730,7 +1753,7 @@
lb_policy_args.args = args;
CreateRoundRobinPolicyLocked(lb_policy_args);
if (grpc_lb_glb_trace.enabled()) {
- gpr_log(GPR_DEBUG, "[grpclb %p] Created new RR policy %p", this,
+ gpr_log(GPR_INFO, "[grpclb %p] Created new RR policy %p", this,
rr_policy_.get());
}
}
@@ -1746,7 +1769,7 @@
}
if (grpc_lb_glb_trace.enabled()) {
gpr_log(
- GPR_DEBUG,
+ GPR_INFO,
"[grpclb %p] Re-resolution requested from the internal RR policy (%p).",
grpclb_policy, grpclb_policy->rr_policy_.get());
}
diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h
new file mode 100644
index 0000000..4d39c4d
--- /dev/null
+++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h
@@ -0,0 +1,36 @@
+/*
+ *
+ * Copyright 2018 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_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_GRPCLB_H
+#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_GRPCLB_H
+
+#include <grpc/support/port_platform.h>
+
+/** Channel arg indicating if a target corresponding to the address is grpclb
+ * loadbalancer. The type of this arg is an integer and the value is treated as
+ * a bool. */
+#define GRPC_ARG_ADDRESS_IS_GRPCLB_LOAD_BALANCER \
+ "grpc.address_is_grpclb_load_balancer"
+/** Channel arg indicating if a target corresponding to the address is a backend
+ * received from a balancer. The type of this arg is an integer and the value is
+ * treated as a bool. */
+#define GRPC_ARG_ADDRESS_IS_BACKEND_FROM_GRPCLB_LOAD_BALANCER \
+ "grpc.address_is_backend_from_grpclb_load_balancer"
+
+#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_GRPCLB_H \
+ */
diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
index 9090c34..76df976 100644
--- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
+++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
@@ -62,31 +62,65 @@
private:
~PickFirst();
+ class PickFirstSubchannelList;
+
+ class PickFirstSubchannelData
+ : public SubchannelData<PickFirstSubchannelList,
+ PickFirstSubchannelData> {
+ public:
+ PickFirstSubchannelData(PickFirstSubchannelList* subchannel_list,
+ const grpc_lb_user_data_vtable* user_data_vtable,
+ const grpc_lb_address& address,
+ grpc_subchannel* subchannel,
+ grpc_combiner* combiner)
+ : SubchannelData(subchannel_list, user_data_vtable, address, subchannel,
+ combiner) {}
+
+ void ProcessConnectivityChangeLocked(
+ grpc_connectivity_state connectivity_state, grpc_error* error) override;
+ };
+
+ class PickFirstSubchannelList
+ : public SubchannelList<PickFirstSubchannelList,
+ PickFirstSubchannelData> {
+ public:
+ PickFirstSubchannelList(PickFirst* policy, TraceFlag* tracer,
+ const grpc_lb_addresses* addresses,
+ grpc_combiner* combiner,
+ grpc_client_channel_factory* client_channel_factory,
+ const grpc_channel_args& args)
+ : SubchannelList(policy, tracer, addresses, combiner,
+ client_channel_factory, args) {
+ // Need to maintain a ref to the LB policy as long as we maintain
+ // any references to subchannels, since the subchannels'
+ // pollset_sets will include the LB policy's pollset_set.
+ policy->Ref(DEBUG_LOCATION, "subchannel_list").release();
+ }
+
+ ~PickFirstSubchannelList() {
+ PickFirst* p = static_cast<PickFirst*>(policy());
+ p->Unref(DEBUG_LOCATION, "subchannel_list");
+ }
+ };
+
void ShutdownLocked() override;
void StartPickingLocked();
void DestroyUnselectedSubchannelsLocked();
- static void OnConnectivityChangedLocked(void* arg, grpc_error* error);
-
- void SubchannelListRefForConnectivityWatch(
- grpc_lb_subchannel_list* subchannel_list, const char* reason);
- void SubchannelListUnrefForConnectivityWatch(
- grpc_lb_subchannel_list* subchannel_list, const char* reason);
-
- /** all our subchannels */
- grpc_lb_subchannel_list* subchannel_list_ = nullptr;
- /** latest pending subchannel list */
- grpc_lb_subchannel_list* latest_pending_subchannel_list_ = nullptr;
- /** selected subchannel in \a subchannel_list */
- grpc_lb_subchannel_data* selected_ = nullptr;
- /** have we started picking? */
+ // All our subchannels.
+ OrphanablePtr<PickFirstSubchannelList> subchannel_list_;
+ // Latest pending subchannel list.
+ OrphanablePtr<PickFirstSubchannelList> latest_pending_subchannel_list_;
+ // Selected subchannel in \a subchannel_list_.
+ PickFirstSubchannelData* selected_ = nullptr;
+ // Have we started picking?
bool started_picking_ = false;
- /** are we shut down? */
+ // Are we shut down?
bool shutdown_ = false;
- /** list of picks that are waiting on connectivity */
+ // List of picks that are waiting on connectivity.
PickState* pending_picks_ = nullptr;
- /** our connectivity state tracker */
+ // Our connectivity state tracker.
grpc_connectivity_state_tracker state_tracker_;
};
@@ -95,7 +129,7 @@
grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE,
"pick_first");
if (grpc_lb_pick_first_trace.enabled()) {
- gpr_log(GPR_DEBUG, "Pick First %p created.", this);
+ gpr_log(GPR_INFO, "Pick First %p created.", this);
}
UpdateLocked(*args.args);
grpc_subchannel_index_ref();
@@ -103,7 +137,7 @@
PickFirst::~PickFirst() {
if (grpc_lb_pick_first_trace.enabled()) {
- gpr_log(GPR_DEBUG, "Destroying Pick First %p", this);
+ gpr_log(GPR_INFO, "Destroying Pick First %p", this);
}
GPR_ASSERT(subchannel_list_ == nullptr);
GPR_ASSERT(latest_pending_subchannel_list_ == nullptr);
@@ -126,7 +160,7 @@
void PickFirst::ShutdownLocked() {
grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel shutdown");
if (grpc_lb_pick_first_trace.enabled()) {
- gpr_log(GPR_DEBUG, "Pick First %p Shutting down", this);
+ gpr_log(GPR_INFO, "Pick First %p Shutting down", this);
}
shutdown_ = true;
PickState* pick;
@@ -137,15 +171,8 @@
}
grpc_connectivity_state_set(&state_tracker_, GRPC_CHANNEL_SHUTDOWN,
GRPC_ERROR_REF(error), "shutdown");
- if (subchannel_list_ != nullptr) {
- grpc_lb_subchannel_list_shutdown_and_unref(subchannel_list_, "pf_shutdown");
- subchannel_list_ = nullptr;
- }
- if (latest_pending_subchannel_list_ != nullptr) {
- grpc_lb_subchannel_list_shutdown_and_unref(latest_pending_subchannel_list_,
- "pf_shutdown");
- latest_pending_subchannel_list_ = nullptr;
- }
+ subchannel_list_.reset();
+ latest_pending_subchannel_list_.reset();
TryReresolutionLocked(&grpc_lb_pick_first_trace, GRPC_ERROR_CANCELLED);
GRPC_ERROR_UNREF(error);
}
@@ -192,14 +219,10 @@
void PickFirst::StartPickingLocked() {
started_picking_ = true;
- if (subchannel_list_ != nullptr && subchannel_list_->num_subchannels > 0) {
- subchannel_list_->checking_subchannel = 0;
- for (size_t i = 0; i < subchannel_list_->num_subchannels; ++i) {
- if (subchannel_list_->subchannels[i].subchannel != nullptr) {
- SubchannelListRefForConnectivityWatch(
- subchannel_list_, "connectivity_watch+start_picking");
- grpc_lb_subchannel_data_start_connectivity_watch(
- &subchannel_list_->subchannels[i]);
+ if (subchannel_list_ != nullptr) {
+ for (size_t i = 0; i < subchannel_list_->num_subchannels(); ++i) {
+ if (subchannel_list_->subchannel(i)->subchannel() != nullptr) {
+ subchannel_list_->subchannel(i)->StartConnectivityWatchLocked();
break;
}
}
@@ -215,7 +238,7 @@
bool PickFirst::PickLocked(PickState* pick) {
// If we have a selected subchannel already, return synchronously.
if (selected_ != nullptr) {
- pick->connected_subchannel = selected_->connected_subchannel;
+ pick->connected_subchannel = selected_->connected_subchannel()->Ref();
return true;
}
// No subchannel selected yet, so handle asynchronously.
@@ -228,11 +251,10 @@
}
void PickFirst::DestroyUnselectedSubchannelsLocked() {
- for (size_t i = 0; i < subchannel_list_->num_subchannels; ++i) {
- grpc_lb_subchannel_data* sd = &subchannel_list_->subchannels[i];
+ for (size_t i = 0; i < subchannel_list_->num_subchannels(); ++i) {
+ PickFirstSubchannelData* sd = subchannel_list_->subchannel(i);
if (selected_ != sd) {
- grpc_lb_subchannel_data_unref_subchannel(sd,
- "selected_different_subchannel");
+ sd->UnrefSubchannelLocked("selected_different_subchannel");
}
}
}
@@ -249,7 +271,7 @@
void PickFirst::PingOneLocked(grpc_closure* on_initiate, grpc_closure* on_ack) {
if (selected_ != nullptr) {
- selected_->connected_subchannel->Ping(on_initiate, on_ack);
+ selected_->connected_subchannel()->Ping(on_initiate, on_ack);
} else {
GRPC_CLOSURE_SCHED(on_initiate,
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Not connected"));
@@ -258,24 +280,6 @@
}
}
-void PickFirst::SubchannelListRefForConnectivityWatch(
- grpc_lb_subchannel_list* subchannel_list, const char* reason) {
- // TODO(roth): We currently track this ref manually. Once the new
- // ClosureRef API is ready and the subchannel_list code has been
- // converted to a C++ API, find a way to hold the RefCountedPtr<>
- // somewhere (maybe in the subchannel_data object) instead of doing
- // this manually.
- auto self = Ref(DEBUG_LOCATION, reason);
- self.release();
- grpc_lb_subchannel_list_ref(subchannel_list, reason);
-}
-
-void PickFirst::SubchannelListUnrefForConnectivityWatch(
- grpc_lb_subchannel_list* subchannel_list, const char* reason) {
- Unref(DEBUG_LOCATION, reason);
- grpc_lb_subchannel_list_unref(subchannel_list, reason);
-}
-
void PickFirst::UpdateLocked(const grpc_channel_args& args) {
const grpc_arg* arg = grpc_channel_args_find(&args, GRPC_ARG_LB_ADDRESSES);
if (arg == nullptr || arg->type != GRPC_ARG_POINTER) {
@@ -295,75 +299,67 @@
return;
}
const grpc_lb_addresses* addresses =
- (const grpc_lb_addresses*)arg->value.pointer.p;
+ static_cast<const grpc_lb_addresses*>(arg->value.pointer.p);
if (grpc_lb_pick_first_trace.enabled()) {
gpr_log(GPR_INFO,
"Pick First %p received update with %" PRIuPTR " addresses", this,
addresses->num_addresses);
}
- grpc_lb_subchannel_list* subchannel_list = grpc_lb_subchannel_list_create(
+ auto subchannel_list = MakeOrphanable<PickFirstSubchannelList>(
this, &grpc_lb_pick_first_trace, addresses, combiner(),
- client_channel_factory(), args, &PickFirst::OnConnectivityChangedLocked);
- if (subchannel_list->num_subchannels == 0) {
+ client_channel_factory(), args);
+ if (subchannel_list->num_subchannels() == 0) {
// Empty update or no valid subchannels. Unsubscribe from all current
// subchannels and put the channel in TRANSIENT_FAILURE.
grpc_connectivity_state_set(
&state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"),
"pf_update_empty");
- if (subchannel_list_ != nullptr) {
- grpc_lb_subchannel_list_shutdown_and_unref(subchannel_list_,
- "sl_shutdown_empty_update");
- }
- subchannel_list_ = subchannel_list; // Empty list.
+ subchannel_list_ = std::move(subchannel_list); // Empty list.
selected_ = nullptr;
return;
}
if (selected_ == nullptr) {
// We don't yet have a selected subchannel, so replace the current
// subchannel list immediately.
- if (subchannel_list_ != nullptr) {
- grpc_lb_subchannel_list_shutdown_and_unref(subchannel_list_,
- "pf_update_before_selected");
+ subchannel_list_ = std::move(subchannel_list);
+ // If we've started picking, start trying to connect to the first
+ // subchannel in the new list.
+ if (started_picking_) {
+ subchannel_list_->subchannel(0)->StartConnectivityWatchLocked();
}
- subchannel_list_ = subchannel_list;
} else {
// We do have a selected subchannel.
// Check if it's present in the new list. If so, we're done.
- for (size_t i = 0; i < subchannel_list->num_subchannels; ++i) {
- grpc_lb_subchannel_data* sd = &subchannel_list->subchannels[i];
- if (sd->subchannel == selected_->subchannel) {
+ for (size_t i = 0; i < subchannel_list->num_subchannels(); ++i) {
+ PickFirstSubchannelData* sd = subchannel_list->subchannel(i);
+ if (sd->subchannel() == selected_->subchannel()) {
// The currently selected subchannel is in the update: we are done.
if (grpc_lb_pick_first_trace.enabled()) {
gpr_log(GPR_INFO,
"Pick First %p found already selected subchannel %p "
"at update index %" PRIuPTR " of %" PRIuPTR "; update done",
- this, selected_->subchannel, i,
- subchannel_list->num_subchannels);
+ this, selected_->subchannel(), i,
+ subchannel_list->num_subchannels());
}
- if (selected_->connected_subchannel != nullptr) {
- sd->connected_subchannel = selected_->connected_subchannel;
+ // Make sure it's in state READY. It might not be if we grabbed
+ // the combiner while a connectivity state notification
+ // informing us otherwise is pending.
+ // Note that CheckConnectivityStateLocked() also takes a ref to
+ // the connected subchannel.
+ grpc_error* error = GRPC_ERROR_NONE;
+ if (sd->CheckConnectivityStateLocked(&error) == GRPC_CHANNEL_READY) {
+ selected_ = sd;
+ subchannel_list_ = std::move(subchannel_list);
+ DestroyUnselectedSubchannelsLocked();
+ sd->StartConnectivityWatchLocked();
+ // If there was a previously pending update (which may or may
+ // not have contained the currently selected subchannel), drop
+ // it, so that it doesn't override what we've done here.
+ latest_pending_subchannel_list_.reset();
+ return;
}
- selected_ = sd;
- if (subchannel_list_ != nullptr) {
- grpc_lb_subchannel_list_shutdown_and_unref(
- subchannel_list_, "pf_update_includes_selected");
- }
- subchannel_list_ = subchannel_list;
- DestroyUnselectedSubchannelsLocked();
- SubchannelListRefForConnectivityWatch(
- subchannel_list, "connectivity_watch+replace_selected");
- grpc_lb_subchannel_data_start_connectivity_watch(sd);
- // If there was a previously pending update (which may or may
- // not have contained the currently selected subchannel), drop
- // it, so that it doesn't override what we've done here.
- if (latest_pending_subchannel_list_ != nullptr) {
- grpc_lb_subchannel_list_shutdown_and_unref(
- latest_pending_subchannel_list_,
- "pf_update_includes_selected+outdated");
- latest_pending_subchannel_list_ = nullptr;
- }
- return;
+ GRPC_ERROR_UNREF(error);
}
}
// Not keeping the previous selected subchannel, so set the latest
@@ -372,88 +368,66 @@
// subchannel list.
if (latest_pending_subchannel_list_ != nullptr) {
if (grpc_lb_pick_first_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"Pick First %p Shutting down latest pending subchannel list "
"%p, about to be replaced by newer latest %p",
- this, latest_pending_subchannel_list_, subchannel_list);
+ this, latest_pending_subchannel_list_.get(),
+ subchannel_list.get());
}
- grpc_lb_subchannel_list_shutdown_and_unref(
- latest_pending_subchannel_list_, "sl_outdated_dont_smash");
}
- latest_pending_subchannel_list_ = subchannel_list;
- }
- // If we've started picking, start trying to connect to the first
- // subchannel in the new list.
- if (started_picking_) {
- SubchannelListRefForConnectivityWatch(subchannel_list,
- "connectivity_watch+update");
- grpc_lb_subchannel_data_start_connectivity_watch(
- &subchannel_list->subchannels[0]);
+ latest_pending_subchannel_list_ = std::move(subchannel_list);
+ // If we've started picking, start trying to connect to the first
+ // subchannel in the new list.
+ if (started_picking_) {
+ latest_pending_subchannel_list_->subchannel(0)
+ ->StartConnectivityWatchLocked();
+ }
}
}
-void PickFirst::OnConnectivityChangedLocked(void* arg, grpc_error* error) {
- grpc_lb_subchannel_data* sd = static_cast<grpc_lb_subchannel_data*>(arg);
- PickFirst* p = static_cast<PickFirst*>(sd->subchannel_list->policy);
- if (grpc_lb_pick_first_trace.enabled()) {
- gpr_log(GPR_DEBUG,
- "Pick First %p connectivity changed for subchannel %p (%" PRIuPTR
- " of %" PRIuPTR
- "), subchannel_list %p: state=%s p->shutdown_=%d "
- "sd->subchannel_list->shutting_down=%d error=%s",
- p, sd->subchannel, sd->subchannel_list->checking_subchannel,
- sd->subchannel_list->num_subchannels, sd->subchannel_list,
- grpc_connectivity_state_name(sd->pending_connectivity_state_unsafe),
- p->shutdown_, sd->subchannel_list->shutting_down,
- grpc_error_string(error));
- }
- // If the policy is shutting down, unref and return.
- if (p->shutdown_) {
- grpc_lb_subchannel_data_stop_connectivity_watch(sd);
- grpc_lb_subchannel_data_unref_subchannel(sd, "pf_shutdown");
- p->SubchannelListUnrefForConnectivityWatch(sd->subchannel_list,
- "pf_shutdown");
- return;
- }
- // If the subchannel list is shutting down, stop watching.
- if (sd->subchannel_list->shutting_down || error == GRPC_ERROR_CANCELLED) {
- grpc_lb_subchannel_data_stop_connectivity_watch(sd);
- grpc_lb_subchannel_data_unref_subchannel(sd, "pf_sl_shutdown");
- p->SubchannelListUnrefForConnectivityWatch(sd->subchannel_list,
- "pf_sl_shutdown");
- return;
- }
- // If we're still here, the notification must be for a subchannel in
- // either the current or latest pending subchannel lists.
- GPR_ASSERT(sd->subchannel_list == p->subchannel_list_ ||
- sd->subchannel_list == p->latest_pending_subchannel_list_);
- // Update state.
- sd->curr_connectivity_state = sd->pending_connectivity_state_unsafe;
+void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked(
+ grpc_connectivity_state connectivity_state, grpc_error* error) {
+ PickFirst* p = static_cast<PickFirst*>(subchannel_list()->policy());
+ // The notification must be for a subchannel in either the current or
+ // latest pending subchannel lists.
+ GPR_ASSERT(subchannel_list() == p->subchannel_list_.get() ||
+ subchannel_list() == p->latest_pending_subchannel_list_.get());
// Handle updates for the currently selected subchannel.
- if (p->selected_ == sd) {
+ if (p->selected_ == this) {
+ if (grpc_lb_pick_first_trace.enabled()) {
+ gpr_log(GPR_INFO,
+ "Pick First %p connectivity changed for selected subchannel", p);
+ }
// If the new state is anything other than READY and there is a
// pending update, switch to the pending update.
- if (sd->curr_connectivity_state != GRPC_CHANNEL_READY &&
+ if (connectivity_state != GRPC_CHANNEL_READY &&
p->latest_pending_subchannel_list_ != nullptr) {
+ if (grpc_lb_pick_first_trace.enabled()) {
+ gpr_log(GPR_INFO,
+ "Pick First %p promoting pending subchannel list %p to "
+ "replace %p",
+ p, p->latest_pending_subchannel_list_.get(),
+ p->subchannel_list_.get());
+ }
p->selected_ = nullptr;
- grpc_lb_subchannel_data_stop_connectivity_watch(sd);
- p->SubchannelListUnrefForConnectivityWatch(
- sd->subchannel_list, "selected_not_ready+switch_to_update");
- grpc_lb_subchannel_list_shutdown_and_unref(
- p->subchannel_list_, "selected_not_ready+switch_to_update");
- p->subchannel_list_ = p->latest_pending_subchannel_list_;
- p->latest_pending_subchannel_list_ = nullptr;
+ StopConnectivityWatchLocked();
+ p->subchannel_list_ = std::move(p->latest_pending_subchannel_list_);
grpc_connectivity_state_set(
&p->state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE,
- GRPC_ERROR_REF(error), "selected_not_ready+switch_to_update");
+ error != GRPC_ERROR_NONE
+ ? GRPC_ERROR_REF(error)
+ : GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+ "selected subchannel not ready; switching to pending "
+ "update"),
+ "selected_not_ready+switch_to_update");
} else {
// TODO(juanlishen): we re-resolve when the selected subchannel goes to
// TRANSIENT_FAILURE because we used to shut down in this case before
// re-resolution is introduced. But we need to investigate whether we
// really want to take any action instead of waiting for the selected
// subchannel reconnecting.
- GPR_ASSERT(sd->curr_connectivity_state != GRPC_CHANNEL_SHUTDOWN);
- if (sd->curr_connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
+ GPR_ASSERT(connectivity_state != GRPC_CHANNEL_SHUTDOWN);
+ if (connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
// If the selected channel goes bad, request a re-resolution.
grpc_connectivity_state_set(&p->state_tracker_, GRPC_CHANNEL_IDLE,
GRPC_ERROR_NONE,
@@ -462,19 +436,16 @@
p->TryReresolutionLocked(&grpc_lb_pick_first_trace, GRPC_ERROR_NONE);
// In transient failure. Rely on re-resolution to recover.
p->selected_ = nullptr;
- grpc_lb_subchannel_data_stop_connectivity_watch(sd);
- p->SubchannelListUnrefForConnectivityWatch(sd->subchannel_list,
- "pf_selected_shutdown");
- grpc_lb_subchannel_data_unref_subchannel(
- sd, "pf_selected_shutdown"); // Unrefs connected subchannel
+ UnrefSubchannelLocked("pf_selected_shutdown");
+ StopConnectivityWatchLocked();
} else {
- grpc_connectivity_state_set(&p->state_tracker_,
- sd->curr_connectivity_state,
+ grpc_connectivity_state_set(&p->state_tracker_, connectivity_state,
GRPC_ERROR_REF(error), "selected_changed");
// Renew notification.
- grpc_lb_subchannel_data_start_connectivity_watch(sd);
+ RenewConnectivityWatchLocked();
}
}
+ GRPC_ERROR_UNREF(error);
return;
}
// If we get here, there are two possible cases:
@@ -486,26 +457,27 @@
// for a subchannel in p->latest_pending_subchannel_list_. The
// goal here is to find a subchannel from the update that we can
// select in place of the current one.
- switch (sd->curr_connectivity_state) {
+ switch (connectivity_state) {
case GRPC_CHANNEL_READY: {
// Case 2. Promote p->latest_pending_subchannel_list_ to
// p->subchannel_list_.
- sd->connected_subchannel =
- grpc_subchannel_get_connected_subchannel(sd->subchannel);
- if (sd->subchannel_list == p->latest_pending_subchannel_list_) {
- GPR_ASSERT(p->subchannel_list_ != nullptr);
- grpc_lb_subchannel_list_shutdown_and_unref(p->subchannel_list_,
- "finish_update");
- p->subchannel_list_ = p->latest_pending_subchannel_list_;
- p->latest_pending_subchannel_list_ = nullptr;
+ if (subchannel_list() == p->latest_pending_subchannel_list_.get()) {
+ if (grpc_lb_pick_first_trace.enabled()) {
+ gpr_log(GPR_INFO,
+ "Pick First %p promoting pending subchannel list %p to "
+ "replace %p",
+ p, p->latest_pending_subchannel_list_.get(),
+ p->subchannel_list_.get());
+ }
+ p->subchannel_list_ = std::move(p->latest_pending_subchannel_list_);
}
// Cases 1 and 2.
grpc_connectivity_state_set(&p->state_tracker_, GRPC_CHANNEL_READY,
GRPC_ERROR_NONE, "connecting_ready");
- p->selected_ = sd;
+ p->selected_ = this;
if (grpc_lb_pick_first_trace.enabled()) {
gpr_log(GPR_INFO, "Pick First %p selected subchannel %p", p,
- sd->subchannel);
+ subchannel());
}
// Drop all other subchannels, since we are now connected.
p->DestroyUnselectedSubchannelsLocked();
@@ -513,7 +485,8 @@
PickState* pick;
while ((pick = p->pending_picks_)) {
p->pending_picks_ = pick->next;
- pick->connected_subchannel = p->selected_->connected_subchannel;
+ pick->connected_subchannel =
+ p->selected_->connected_subchannel()->Ref();
if (grpc_lb_pick_first_trace.enabled()) {
gpr_log(GPR_INFO,
"Servicing pending pick with selected subchannel %p",
@@ -522,45 +495,43 @@
GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_NONE);
}
// Renew notification.
- grpc_lb_subchannel_data_start_connectivity_watch(sd);
+ RenewConnectivityWatchLocked();
break;
}
case GRPC_CHANNEL_TRANSIENT_FAILURE: {
- grpc_lb_subchannel_data_stop_connectivity_watch(sd);
+ StopConnectivityWatchLocked();
+ PickFirstSubchannelData* sd = this;
do {
- sd->subchannel_list->checking_subchannel =
- (sd->subchannel_list->checking_subchannel + 1) %
- sd->subchannel_list->num_subchannels;
- sd = &sd->subchannel_list
- ->subchannels[sd->subchannel_list->checking_subchannel];
- } while (sd->subchannel == nullptr);
+ size_t next_index =
+ (sd->Index() + 1) % subchannel_list()->num_subchannels();
+ sd = subchannel_list()->subchannel(next_index);
+ } while (sd->subchannel() == nullptr);
// Case 1: Only set state to TRANSIENT_FAILURE if we've tried
// all subchannels.
- if (sd->subchannel_list->checking_subchannel == 0 &&
- sd->subchannel_list == p->subchannel_list_) {
+ if (sd->Index() == 0 && subchannel_list() == p->subchannel_list_.get()) {
grpc_connectivity_state_set(
&p->state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_ERROR_REF(error), "connecting_transient_failure");
}
- // Reuses the connectivity refs from the previous watch.
- grpc_lb_subchannel_data_start_connectivity_watch(sd);
+ sd->StartConnectivityWatchLocked();
break;
}
case GRPC_CHANNEL_CONNECTING:
case GRPC_CHANNEL_IDLE: {
// Only update connectivity state in case 1.
- if (sd->subchannel_list == p->subchannel_list_) {
+ if (subchannel_list() == p->subchannel_list_.get()) {
grpc_connectivity_state_set(&p->state_tracker_, GRPC_CHANNEL_CONNECTING,
GRPC_ERROR_REF(error),
"connecting_changed");
}
// Renew notification.
- grpc_lb_subchannel_data_start_connectivity_watch(sd);
+ RenewConnectivityWatchLocked();
break;
}
case GRPC_CHANNEL_SHUTDOWN:
GPR_UNREACHABLE_CODE(break);
}
+ GRPC_ERROR_UNREF(error);
}
//
diff --git a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
index e534131..79e8ad5 100644
--- a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
+++ b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
@@ -73,23 +73,127 @@
private:
~RoundRobin();
+ // Forward declaration.
+ class RoundRobinSubchannelList;
+
+ // Data for a particular subchannel in a subchannel list.
+ // This subclass adds the following functionality:
+ // - Tracks user_data associated with each address, which will be
+ // returned along with picks that select the subchannel.
+ // - Tracks the previous connectivity state of the subchannel, so that
+ // we know how many subchannels are in each state.
+ class RoundRobinSubchannelData
+ : public SubchannelData<RoundRobinSubchannelList,
+ RoundRobinSubchannelData> {
+ public:
+ RoundRobinSubchannelData(RoundRobinSubchannelList* subchannel_list,
+ const grpc_lb_user_data_vtable* user_data_vtable,
+ const grpc_lb_address& address,
+ grpc_subchannel* subchannel,
+ grpc_combiner* combiner)
+ : SubchannelData(subchannel_list, user_data_vtable, address, subchannel,
+ combiner),
+ user_data_vtable_(user_data_vtable),
+ user_data_(user_data_vtable_ != nullptr
+ ? user_data_vtable_->copy(address.user_data)
+ : nullptr) {}
+
+ void UnrefSubchannelLocked(const char* reason) override {
+ SubchannelData::UnrefSubchannelLocked(reason);
+ if (user_data_ != nullptr) {
+ GPR_ASSERT(user_data_vtable_ != nullptr);
+ user_data_vtable_->destroy(user_data_);
+ user_data_ = nullptr;
+ }
+ }
+
+ void* user_data() const { return user_data_; }
+
+ grpc_connectivity_state connectivity_state() const {
+ return last_connectivity_state_;
+ }
+
+ void UpdateConnectivityStateLocked(
+ grpc_connectivity_state connectivity_state, grpc_error* error);
+
+ private:
+ void ProcessConnectivityChangeLocked(
+ grpc_connectivity_state connectivity_state, grpc_error* error) override;
+
+ const grpc_lb_user_data_vtable* user_data_vtable_;
+ void* user_data_ = nullptr;
+ grpc_connectivity_state last_connectivity_state_ = GRPC_CHANNEL_IDLE;
+ };
+
+ // A list of subchannels.
+ class RoundRobinSubchannelList
+ : public SubchannelList<RoundRobinSubchannelList,
+ RoundRobinSubchannelData> {
+ public:
+ RoundRobinSubchannelList(
+ RoundRobin* policy, TraceFlag* tracer,
+ const grpc_lb_addresses* addresses, grpc_combiner* combiner,
+ grpc_client_channel_factory* client_channel_factory,
+ const grpc_channel_args& args)
+ : SubchannelList(policy, tracer, addresses, combiner,
+ client_channel_factory, args) {
+ // Need to maintain a ref to the LB policy as long as we maintain
+ // any references to subchannels, since the subchannels'
+ // pollset_sets will include the LB policy's pollset_set.
+ policy->Ref(DEBUG_LOCATION, "subchannel_list").release();
+ }
+
+ ~RoundRobinSubchannelList() {
+ GRPC_ERROR_UNREF(last_transient_failure_error_);
+ RoundRobin* p = static_cast<RoundRobin*>(policy());
+ p->Unref(DEBUG_LOCATION, "subchannel_list");
+ }
+
+ // Starts watching the subchannels in this list.
+ void StartWatchingLocked();
+
+ // Updates the counters of subchannels in each state when a
+ // subchannel transitions from old_state to new_state.
+ // transient_failure_error is the error that is reported when
+ // new_state is TRANSIENT_FAILURE.
+ void UpdateStateCountersLocked(grpc_connectivity_state old_state,
+ grpc_connectivity_state new_state,
+ grpc_error* transient_failure_error);
+
+ // If this subchannel list is the RR policy's current subchannel
+ // list, updates the RR policy's connectivity state based on the
+ // subchannel list's state counters.
+ void MaybeUpdateRoundRobinConnectivityStateLocked();
+
+ // Updates the RR policy's overall state based on the counters of
+ // subchannels in each state.
+ void UpdateRoundRobinStateFromSubchannelStateCountsLocked();
+
+ size_t GetNextReadySubchannelIndexLocked();
+ void UpdateLastReadySubchannelIndexLocked(size_t last_ready_index);
+
+ private:
+ size_t num_ready_ = 0;
+ size_t num_connecting_ = 0;
+ size_t num_transient_failure_ = 0;
+ grpc_error* last_transient_failure_error_ = GRPC_ERROR_NONE;
+ size_t last_ready_index_ = -1; // Index into list of last pick.
+ };
+
void ShutdownLocked() override;
void StartPickingLocked();
- size_t GetNextReadySubchannelIndexLocked();
- void UpdateLastReadySubchannelIndexLocked(size_t last_ready_index);
- void UpdateConnectivityStatusLocked(grpc_lb_subchannel_data* sd,
- grpc_error* error);
-
- static void OnConnectivityChangedLocked(void* arg, grpc_error* error);
-
- void SubchannelListRefForConnectivityWatch(
- grpc_lb_subchannel_list* subchannel_list, const char* reason);
- void SubchannelListUnrefForConnectivityWatch(
- grpc_lb_subchannel_list* subchannel_list, const char* reason);
+ bool DoPickLocked(PickState* pick);
+ void DrainPendingPicksLocked();
/** list of subchannels */
- grpc_lb_subchannel_list* subchannel_list_ = nullptr;
+ OrphanablePtr<RoundRobinSubchannelList> subchannel_list_;
+ /** Latest version of the subchannel list.
+ * Subchannel connectivity callbacks will only promote updated subchannel
+ * lists if they equal \a latest_pending_subchannel_list. In other words,
+ * racing callbacks that reference outdated subchannel lists won't perform any
+ * update. */
+ OrphanablePtr<RoundRobinSubchannelList> latest_pending_subchannel_list_;
/** have we started picking? */
bool started_picking_ = false;
/** are we shutting down? */
@@ -98,14 +202,6 @@
PickState* pending_picks_ = nullptr;
/** our connectivity state tracker */
grpc_connectivity_state_tracker state_tracker_;
- /** Index into subchannels for last pick. */
- size_t last_ready_subchannel_index_ = 0;
- /** Latest version of the subchannel list.
- * Subchannel connectivity callbacks will only promote updated subchannel
- * lists if they equal \a latest_pending_subchannel_list. In other words,
- * racing callbacks that reference outdated subchannel lists won't perform any
- * update. */
- grpc_lb_subchannel_list* latest_pending_subchannel_list_ = nullptr;
};
RoundRobin::RoundRobin(const Args& args) : LoadBalancingPolicy(args) {
@@ -114,15 +210,15 @@
"round_robin");
UpdateLocked(*args.args);
if (grpc_lb_round_robin_trace.enabled()) {
- gpr_log(GPR_DEBUG, "[RR %p] Created with %" PRIuPTR " subchannels", this,
- subchannel_list_->num_subchannels);
+ gpr_log(GPR_INFO, "[RR %p] Created with %" PRIuPTR " subchannels", this,
+ subchannel_list_->num_subchannels());
}
grpc_subchannel_index_ref();
}
RoundRobin::~RoundRobin() {
if (grpc_lb_round_robin_trace.enabled()) {
- gpr_log(GPR_DEBUG, "[RR %p] Destroying Round Robin policy", this);
+ gpr_log(GPR_INFO, "[RR %p] Destroying Round Robin policy", this);
}
GPR_ASSERT(subchannel_list_ == nullptr);
GPR_ASSERT(latest_pending_subchannel_list_ == nullptr);
@@ -131,68 +227,6 @@
grpc_subchannel_index_unref();
}
-/** Returns the index into p->subchannel_list->subchannels of the next
- * subchannel in READY state, or p->subchannel_list->num_subchannels if no
- * subchannel is READY.
- *
- * Note that this function does *not* update p->last_ready_subchannel_index.
- * The caller must do that if it returns a pick. */
-size_t RoundRobin::GetNextReadySubchannelIndexLocked() {
- GPR_ASSERT(subchannel_list_ != nullptr);
- if (grpc_lb_round_robin_trace.enabled()) {
- gpr_log(GPR_INFO,
- "[RR %p] getting next ready subchannel (out of %" PRIuPTR
- "), "
- "last_ready_subchannel_index=%" PRIuPTR,
- this, subchannel_list_->num_subchannels,
- last_ready_subchannel_index_);
- }
- for (size_t i = 0; i < subchannel_list_->num_subchannels; ++i) {
- const size_t index = (i + last_ready_subchannel_index_ + 1) %
- subchannel_list_->num_subchannels;
- if (grpc_lb_round_robin_trace.enabled()) {
- gpr_log(
- GPR_DEBUG,
- "[RR %p] checking subchannel %p, subchannel_list %p, index %" PRIuPTR
- ": state=%s",
- this, subchannel_list_->subchannels[index].subchannel,
- subchannel_list_, index,
- grpc_connectivity_state_name(
- subchannel_list_->subchannels[index].curr_connectivity_state));
- }
- if (subchannel_list_->subchannels[index].curr_connectivity_state ==
- GRPC_CHANNEL_READY) {
- if (grpc_lb_round_robin_trace.enabled()) {
- gpr_log(GPR_DEBUG,
- "[RR %p] found next ready subchannel (%p) at index %" PRIuPTR
- " of subchannel_list %p",
- this, subchannel_list_->subchannels[index].subchannel, index,
- subchannel_list_);
- }
- return index;
- }
- }
- if (grpc_lb_round_robin_trace.enabled()) {
- gpr_log(GPR_DEBUG, "[RR %p] no subchannels in ready state", this);
- }
- return subchannel_list_->num_subchannels;
-}
-
-// Sets last_ready_subchannel_index_ to last_ready_index.
-void RoundRobin::UpdateLastReadySubchannelIndexLocked(size_t last_ready_index) {
- GPR_ASSERT(last_ready_index < subchannel_list_->num_subchannels);
- last_ready_subchannel_index_ = last_ready_index;
- if (grpc_lb_round_robin_trace.enabled()) {
- gpr_log(GPR_DEBUG,
- "[RR %p] setting last_ready_subchannel_index=%" PRIuPTR
- " (SC %p, CSC %p)",
- this, last_ready_index,
- subchannel_list_->subchannels[last_ready_index].subchannel,
- subchannel_list_->subchannels[last_ready_index]
- .connected_subchannel.get());
- }
-}
-
void RoundRobin::HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) {
PickState* pick;
while ((pick = pending_picks_) != nullptr) {
@@ -207,7 +241,7 @@
void RoundRobin::ShutdownLocked() {
grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel shutdown");
if (grpc_lb_round_robin_trace.enabled()) {
- gpr_log(GPR_DEBUG, "[RR %p] Shutting down", this);
+ gpr_log(GPR_INFO, "[RR %p] Shutting down", this);
}
shutdown_ = true;
PickState* pick;
@@ -218,16 +252,8 @@
}
grpc_connectivity_state_set(&state_tracker_, GRPC_CHANNEL_SHUTDOWN,
GRPC_ERROR_REF(error), "rr_shutdown");
- if (subchannel_list_ != nullptr) {
- grpc_lb_subchannel_list_shutdown_and_unref(subchannel_list_,
- "sl_shutdown_rr_shutdown");
- subchannel_list_ = nullptr;
- }
- if (latest_pending_subchannel_list_ != nullptr) {
- grpc_lb_subchannel_list_shutdown_and_unref(
- latest_pending_subchannel_list_, "sl_shutdown_pending_rr_shutdown");
- latest_pending_subchannel_list_ = nullptr;
- }
+ subchannel_list_.reset();
+ latest_pending_subchannel_list_.reset();
TryReresolutionLocked(&grpc_lb_round_robin_trace, GRPC_ERROR_CANCELLED);
GRPC_ERROR_UNREF(error);
}
@@ -273,34 +299,9 @@
GRPC_ERROR_UNREF(error);
}
-void RoundRobin::SubchannelListRefForConnectivityWatch(
- grpc_lb_subchannel_list* subchannel_list, const char* reason) {
- // TODO(roth): We currently track this ref manually. Once the new
- // ClosureRef API is ready and the subchannel_list code has been
- // converted to a C++ API, find a way to hold the RefCountedPtr<>
- // somewhere (maybe in the subchannel_data object) instead of doing
- // this manually.
- auto self = Ref(DEBUG_LOCATION, reason);
- self.release();
- grpc_lb_subchannel_list_ref(subchannel_list, reason);
-}
-
-void RoundRobin::SubchannelListUnrefForConnectivityWatch(
- grpc_lb_subchannel_list* subchannel_list, const char* reason) {
- Unref(DEBUG_LOCATION, reason);
- grpc_lb_subchannel_list_unref(subchannel_list, reason);
-}
-
void RoundRobin::StartPickingLocked() {
started_picking_ = true;
- for (size_t i = 0; i < subchannel_list_->num_subchannels; i++) {
- if (subchannel_list_->subchannels[i].subchannel != nullptr) {
- SubchannelListRefForConnectivityWatch(subchannel_list_,
- "connectivity_watch");
- grpc_lb_subchannel_data_start_connectivity_watch(
- &subchannel_list_->subchannels[i]);
- }
- }
+ subchannel_list_->StartWatchingLocked();
}
void RoundRobin::ExitIdleLocked() {
@@ -309,34 +310,48 @@
}
}
+bool RoundRobin::DoPickLocked(PickState* pick) {
+ const size_t next_ready_index =
+ subchannel_list_->GetNextReadySubchannelIndexLocked();
+ if (next_ready_index < subchannel_list_->num_subchannels()) {
+ /* readily available, report right away */
+ RoundRobinSubchannelData* sd =
+ subchannel_list_->subchannel(next_ready_index);
+ GPR_ASSERT(sd->connected_subchannel() != nullptr);
+ pick->connected_subchannel = sd->connected_subchannel()->Ref();
+ if (pick->user_data != nullptr) {
+ *pick->user_data = sd->user_data();
+ }
+ if (grpc_lb_round_robin_trace.enabled()) {
+ gpr_log(GPR_INFO,
+ "[RR %p] Picked target <-- Subchannel %p (connected %p) (sl %p, "
+ "index %" PRIuPTR ")",
+ this, sd->subchannel(), pick->connected_subchannel.get(),
+ sd->subchannel_list(), next_ready_index);
+ }
+ /* only advance the last picked pointer if the selection was used */
+ subchannel_list_->UpdateLastReadySubchannelIndexLocked(next_ready_index);
+ return true;
+ }
+ return false;
+}
+
+void RoundRobin::DrainPendingPicksLocked() {
+ PickState* pick;
+ while ((pick = pending_picks_)) {
+ pending_picks_ = pick->next;
+ GPR_ASSERT(DoPickLocked(pick));
+ GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_NONE);
+ }
+}
+
bool RoundRobin::PickLocked(PickState* pick) {
if (grpc_lb_round_robin_trace.enabled()) {
- gpr_log(GPR_DEBUG, "[RR %p] Trying to pick (shutdown: %d)", this,
- shutdown_);
+ gpr_log(GPR_INFO, "[RR %p] Trying to pick (shutdown: %d)", this, shutdown_);
}
GPR_ASSERT(!shutdown_);
if (subchannel_list_ != nullptr) {
- const size_t next_ready_index = GetNextReadySubchannelIndexLocked();
- if (next_ready_index < subchannel_list_->num_subchannels) {
- /* readily available, report right away */
- grpc_lb_subchannel_data* sd =
- &subchannel_list_->subchannels[next_ready_index];
- pick->connected_subchannel = sd->connected_subchannel;
- if (pick->user_data != nullptr) {
- *pick->user_data = sd->user_data;
- }
- if (grpc_lb_round_robin_trace.enabled()) {
- gpr_log(
- GPR_DEBUG,
- "[RR %p] Picked target <-- Subchannel %p (connected %p) (sl %p, "
- "index %" PRIuPTR ")",
- this, sd->subchannel, pick->connected_subchannel.get(),
- sd->subchannel_list, next_ready_index);
- }
- /* only advance the last picked pointer if the selection was used */
- UpdateLastReadySubchannelIndexLocked(next_ready_index);
- return true;
- }
+ if (DoPickLocked(pick)) return true;
}
/* no pick currently available. Save for later in list of pending picks */
if (!started_picking_) {
@@ -347,36 +362,62 @@
return false;
}
-void UpdateStateCountersLocked(grpc_lb_subchannel_data* sd) {
- grpc_lb_subchannel_list* subchannel_list = sd->subchannel_list;
- GPR_ASSERT(sd->prev_connectivity_state != GRPC_CHANNEL_SHUTDOWN);
- GPR_ASSERT(sd->curr_connectivity_state != GRPC_CHANNEL_SHUTDOWN);
- if (sd->prev_connectivity_state == GRPC_CHANNEL_READY) {
- GPR_ASSERT(subchannel_list->num_ready > 0);
- --subchannel_list->num_ready;
- } else if (sd->prev_connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
- GPR_ASSERT(subchannel_list->num_transient_failures > 0);
- --subchannel_list->num_transient_failures;
- } else if (sd->prev_connectivity_state == GRPC_CHANNEL_IDLE) {
- GPR_ASSERT(subchannel_list->num_idle > 0);
- --subchannel_list->num_idle;
+void RoundRobin::RoundRobinSubchannelList::StartWatchingLocked() {
+ if (num_subchannels() == 0) return;
+ // Check current state of each subchannel synchronously, since any
+ // subchannel already used by some other channel may have a non-IDLE
+ // state.
+ for (size_t i = 0; i < num_subchannels(); ++i) {
+ grpc_error* error = GRPC_ERROR_NONE;
+ grpc_connectivity_state state =
+ subchannel(i)->CheckConnectivityStateLocked(&error);
+ if (state != GRPC_CHANNEL_IDLE) {
+ subchannel(i)->UpdateConnectivityStateLocked(state, error);
+ }
}
- sd->prev_connectivity_state = sd->curr_connectivity_state;
- if (sd->curr_connectivity_state == GRPC_CHANNEL_READY) {
- ++subchannel_list->num_ready;
- } else if (sd->curr_connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
- ++subchannel_list->num_transient_failures;
- } else if (sd->curr_connectivity_state == GRPC_CHANNEL_IDLE) {
- ++subchannel_list->num_idle;
+ // Now set the LB policy's state based on the subchannels' states.
+ UpdateRoundRobinStateFromSubchannelStateCountsLocked();
+ // Start connectivity watch for each subchannel.
+ for (size_t i = 0; i < num_subchannels(); i++) {
+ if (subchannel(i)->subchannel() != nullptr) {
+ subchannel(i)->StartConnectivityWatchLocked();
+ }
}
}
-/** Sets the policy's connectivity status based on that of the passed-in \a sd
- * (the grpc_lb_subchannel_data associated with the updated subchannel) and the
- * subchannel list \a sd belongs to (sd->subchannel_list). \a error will be used
- * only if the policy transitions to state TRANSIENT_FAILURE. */
-void RoundRobin::UpdateConnectivityStatusLocked(grpc_lb_subchannel_data* sd,
- grpc_error* error) {
+void RoundRobin::RoundRobinSubchannelList::UpdateStateCountersLocked(
+ grpc_connectivity_state old_state, grpc_connectivity_state new_state,
+ grpc_error* transient_failure_error) {
+ GPR_ASSERT(old_state != GRPC_CHANNEL_SHUTDOWN);
+ GPR_ASSERT(new_state != GRPC_CHANNEL_SHUTDOWN);
+ if (old_state == GRPC_CHANNEL_READY) {
+ GPR_ASSERT(num_ready_ > 0);
+ --num_ready_;
+ } else if (old_state == GRPC_CHANNEL_CONNECTING) {
+ GPR_ASSERT(num_connecting_ > 0);
+ --num_connecting_;
+ } else if (old_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
+ GPR_ASSERT(num_transient_failure_ > 0);
+ --num_transient_failure_;
+ }
+ if (new_state == GRPC_CHANNEL_READY) {
+ ++num_ready_;
+ } else if (new_state == GRPC_CHANNEL_CONNECTING) {
+ ++num_connecting_;
+ } else if (new_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
+ ++num_transient_failure_;
+ }
+ GRPC_ERROR_UNREF(last_transient_failure_error_);
+ last_transient_failure_error_ = transient_failure_error;
+}
+
+// Sets the RR policy's connectivity state based on the current
+// subchannel list.
+void RoundRobin::RoundRobinSubchannelList::
+ MaybeUpdateRoundRobinConnectivityStateLocked() {
+ RoundRobin* p = static_cast<RoundRobin*>(policy());
+ // Only set connectivity state if this is the current subchannel list.
+ if (p->subchannel_list_.get() != this) return;
/* In priority order. The first rule to match terminates the search (ie, if we
* are on rule n, all previous rules were unfulfilled).
*
@@ -391,155 +432,151 @@
* CHECK: subchannel_list->num_transient_failures ==
* subchannel_list->num_subchannels.
*/
- grpc_lb_subchannel_list* subchannel_list = sd->subchannel_list;
- GPR_ASSERT(sd->curr_connectivity_state != GRPC_CHANNEL_IDLE);
- if (subchannel_list->num_ready > 0) {
+ if (num_ready_ > 0) {
/* 1) READY */
- grpc_connectivity_state_set(&state_tracker_, GRPC_CHANNEL_READY,
+ grpc_connectivity_state_set(&p->state_tracker_, GRPC_CHANNEL_READY,
GRPC_ERROR_NONE, "rr_ready");
- } else if (sd->curr_connectivity_state == GRPC_CHANNEL_CONNECTING) {
+ } else if (num_connecting_ > 0) {
/* 2) CONNECTING */
- grpc_connectivity_state_set(&state_tracker_, GRPC_CHANNEL_CONNECTING,
+ grpc_connectivity_state_set(&p->state_tracker_, GRPC_CHANNEL_CONNECTING,
GRPC_ERROR_NONE, "rr_connecting");
- } else if (subchannel_list->num_transient_failures ==
- subchannel_list->num_subchannels) {
+ } else if (num_transient_failure_ == num_subchannels()) {
/* 3) TRANSIENT_FAILURE */
- grpc_connectivity_state_set(&state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE,
- GRPC_ERROR_REF(error),
+ grpc_connectivity_state_set(&p->state_tracker_,
+ GRPC_CHANNEL_TRANSIENT_FAILURE,
+ GRPC_ERROR_REF(last_transient_failure_error_),
"rr_exhausted_subchannels");
}
- GRPC_ERROR_UNREF(error);
}
-void RoundRobin::OnConnectivityChangedLocked(void* arg, grpc_error* error) {
- grpc_lb_subchannel_data* sd = static_cast<grpc_lb_subchannel_data*>(arg);
- RoundRobin* p = static_cast<RoundRobin*>(sd->subchannel_list->policy);
+void RoundRobin::RoundRobinSubchannelList::
+ UpdateRoundRobinStateFromSubchannelStateCountsLocked() {
+ RoundRobin* p = static_cast<RoundRobin*>(policy());
+ if (num_ready_ > 0) {
+ if (p->subchannel_list_.get() != this) {
+ // Promote this list to p->subchannel_list_.
+ // This list must be p->latest_pending_subchannel_list_, because
+ // any previous update would have been shut down already and
+ // therefore we would not be receiving a notification for them.
+ GPR_ASSERT(p->latest_pending_subchannel_list_.get() == this);
+ GPR_ASSERT(!shutting_down());
+ if (grpc_lb_round_robin_trace.enabled()) {
+ const size_t old_num_subchannels =
+ p->subchannel_list_ != nullptr
+ ? p->subchannel_list_->num_subchannels()
+ : 0;
+ gpr_log(GPR_INFO,
+ "[RR %p] phasing out subchannel list %p (size %" PRIuPTR
+ ") in favor of %p (size %" PRIuPTR ")",
+ p, p->subchannel_list_.get(), old_num_subchannels, this,
+ num_subchannels());
+ }
+ p->subchannel_list_ = std::move(p->latest_pending_subchannel_list_);
+ }
+ // Drain pending picks.
+ p->DrainPendingPicksLocked();
+ }
+ // Update the RR policy's connectivity state if needed.
+ MaybeUpdateRoundRobinConnectivityStateLocked();
+}
+
+void RoundRobin::RoundRobinSubchannelData::UpdateConnectivityStateLocked(
+ grpc_connectivity_state connectivity_state, grpc_error* error) {
+ RoundRobin* p = static_cast<RoundRobin*>(subchannel_list()->policy());
if (grpc_lb_round_robin_trace.enabled()) {
gpr_log(
- GPR_DEBUG,
- "[RR %p] connectivity changed for subchannel %p, subchannel_list %p: "
- "prev_state=%s new_state=%s p->shutdown=%d "
- "sd->subchannel_list->shutting_down=%d error=%s",
- p, sd->subchannel, sd->subchannel_list,
- grpc_connectivity_state_name(sd->prev_connectivity_state),
- grpc_connectivity_state_name(sd->pending_connectivity_state_unsafe),
- p->shutdown_, sd->subchannel_list->shutting_down,
- grpc_error_string(error));
+ GPR_INFO,
+ "[RR %p] connectivity changed for subchannel %p, subchannel_list %p "
+ "(index %" PRIuPTR " of %" PRIuPTR "): prev_state=%s new_state=%s",
+ p, subchannel(), subchannel_list(), Index(),
+ subchannel_list()->num_subchannels(),
+ grpc_connectivity_state_name(last_connectivity_state_),
+ grpc_connectivity_state_name(connectivity_state));
}
- GPR_ASSERT(sd->subchannel != nullptr);
- // If the policy is shutting down, unref and return.
- if (p->shutdown_) {
- grpc_lb_subchannel_data_stop_connectivity_watch(sd);
- grpc_lb_subchannel_data_unref_subchannel(sd, "rr_shutdown");
- p->SubchannelListUnrefForConnectivityWatch(sd->subchannel_list,
- "rr_shutdown");
- return;
- }
- // If the subchannel list is shutting down, stop watching.
- if (sd->subchannel_list->shutting_down || error == GRPC_ERROR_CANCELLED) {
- grpc_lb_subchannel_data_stop_connectivity_watch(sd);
- grpc_lb_subchannel_data_unref_subchannel(sd, "rr_sl_shutdown");
- p->SubchannelListUnrefForConnectivityWatch(sd->subchannel_list,
- "rr_sl_shutdown");
- return;
- }
- // If we're still here, the notification must be for a subchannel in
- // either the current or latest pending subchannel lists.
- GPR_ASSERT(sd->subchannel_list == p->subchannel_list_ ||
- sd->subchannel_list == p->latest_pending_subchannel_list_);
- GPR_ASSERT(sd->pending_connectivity_state_unsafe != GRPC_CHANNEL_SHUTDOWN);
- // Now that we're inside the combiner, copy the pending connectivity
- // state (which was set by the connectivity state watcher) to
- // curr_connectivity_state, which is what we use inside of the combiner.
- sd->curr_connectivity_state = sd->pending_connectivity_state_unsafe;
- // If the sd's new state is TRANSIENT_FAILURE, unref the *connected*
- // subchannel, if any.
- switch (sd->curr_connectivity_state) {
- case GRPC_CHANNEL_TRANSIENT_FAILURE: {
- sd->connected_subchannel.reset();
- if (grpc_lb_round_robin_trace.enabled()) {
- gpr_log(GPR_DEBUG,
- "[RR %p] Subchannel %p has gone into TRANSIENT_FAILURE. "
- "Requesting re-resolution",
- p, sd->subchannel);
- }
- p->TryReresolutionLocked(&grpc_lb_round_robin_trace, GRPC_ERROR_NONE);
- break;
+ subchannel_list()->UpdateStateCountersLocked(last_connectivity_state_,
+ connectivity_state, error);
+ last_connectivity_state_ = connectivity_state;
+}
+
+void RoundRobin::RoundRobinSubchannelData::ProcessConnectivityChangeLocked(
+ grpc_connectivity_state connectivity_state, grpc_error* error) {
+ RoundRobin* p = static_cast<RoundRobin*>(subchannel_list()->policy());
+ GPR_ASSERT(subchannel() != nullptr);
+ // If the new state is TRANSIENT_FAILURE, re-resolve.
+ // Only do this if we've started watching, not at startup time.
+ // Otherwise, if the subchannel was already in state TRANSIENT_FAILURE
+ // when the subchannel list was created, we'd wind up in a constant
+ // loop of re-resolution.
+ if (connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
+ if (grpc_lb_round_robin_trace.enabled()) {
+ gpr_log(GPR_INFO,
+ "[RR %p] Subchannel %p has gone into TRANSIENT_FAILURE. "
+ "Requesting re-resolution",
+ p, subchannel());
}
- case GRPC_CHANNEL_READY: {
- if (sd->connected_subchannel == nullptr) {
- sd->connected_subchannel =
- grpc_subchannel_get_connected_subchannel(sd->subchannel);
- }
- if (sd->subchannel_list != p->subchannel_list_) {
- // promote sd->subchannel_list to p->subchannel_list_.
- // sd->subchannel_list must be equal to
- // p->latest_pending_subchannel_list_ because we have already filtered
- // for sds belonging to outdated subchannel lists.
- GPR_ASSERT(sd->subchannel_list == p->latest_pending_subchannel_list_);
- GPR_ASSERT(!sd->subchannel_list->shutting_down);
- if (grpc_lb_round_robin_trace.enabled()) {
- const size_t num_subchannels =
- p->subchannel_list_ != nullptr
- ? p->subchannel_list_->num_subchannels
- : 0;
- gpr_log(GPR_DEBUG,
- "[RR %p] phasing out subchannel list %p (size %" PRIuPTR
- ") in favor of %p (size %" PRIuPTR ")",
- p, p->subchannel_list_, num_subchannels, sd->subchannel_list,
- num_subchannels);
- }
- if (p->subchannel_list_ != nullptr) {
- // dispose of the current subchannel_list
- grpc_lb_subchannel_list_shutdown_and_unref(p->subchannel_list_,
- "sl_phase_out_shutdown");
- }
- p->subchannel_list_ = p->latest_pending_subchannel_list_;
- p->latest_pending_subchannel_list_ = nullptr;
- }
- /* at this point we know there's at least one suitable subchannel. Go
- * ahead and pick one and notify the pending suitors in
- * p->pending_picks. This preemptively replicates rr_pick()'s actions. */
- const size_t next_ready_index = p->GetNextReadySubchannelIndexLocked();
- GPR_ASSERT(next_ready_index < p->subchannel_list_->num_subchannels);
- grpc_lb_subchannel_data* selected =
- &p->subchannel_list_->subchannels[next_ready_index];
- if (p->pending_picks_ != nullptr) {
- // if the selected subchannel is going to be used for the pending
- // picks, update the last picked pointer
- p->UpdateLastReadySubchannelIndexLocked(next_ready_index);
- }
- PickState* pick;
- while ((pick = p->pending_picks_)) {
- p->pending_picks_ = pick->next;
- pick->connected_subchannel = selected->connected_subchannel;
- if (pick->user_data != nullptr) {
- *pick->user_data = selected->user_data;
- }
- if (grpc_lb_round_robin_trace.enabled()) {
- gpr_log(GPR_DEBUG,
- "[RR %p] Fulfilling pending pick. Target <-- subchannel %p "
- "(subchannel_list %p, index %" PRIuPTR ")",
- p, selected->subchannel, p->subchannel_list_,
- next_ready_index);
- }
- GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_NONE);
- }
- break;
- }
- case GRPC_CHANNEL_SHUTDOWN:
- GPR_UNREACHABLE_CODE(return );
- case GRPC_CHANNEL_CONNECTING:
- case GRPC_CHANNEL_IDLE:; // fallthrough
+ p->TryReresolutionLocked(&grpc_lb_round_robin_trace, GRPC_ERROR_NONE);
}
// Update state counters.
- UpdateStateCountersLocked(sd);
- // Only update connectivity based on the selected subchannel list.
- if (sd->subchannel_list == p->subchannel_list_) {
- p->UpdateConnectivityStatusLocked(sd, GRPC_ERROR_REF(error));
+ UpdateConnectivityStateLocked(connectivity_state, error);
+ // Update overall state and renew notification.
+ subchannel_list()->UpdateRoundRobinStateFromSubchannelStateCountsLocked();
+ RenewConnectivityWatchLocked();
+}
+
+/** Returns the index into p->subchannel_list->subchannels of the next
+ * subchannel in READY state, or p->subchannel_list->num_subchannels if no
+ * subchannel is READY.
+ *
+ * Note that this function does *not* update p->last_ready_subchannel_index.
+ * The caller must do that if it returns a pick. */
+size_t
+RoundRobin::RoundRobinSubchannelList::GetNextReadySubchannelIndexLocked() {
+ if (grpc_lb_round_robin_trace.enabled()) {
+ gpr_log(GPR_INFO,
+ "[RR %p] getting next ready subchannel (out of %" PRIuPTR
+ "), last_ready_index=%" PRIuPTR,
+ policy(), num_subchannels(), last_ready_index_);
}
- // Renew notification.
- grpc_lb_subchannel_data_start_connectivity_watch(sd);
+ for (size_t i = 0; i < num_subchannels(); ++i) {
+ const size_t index = (i + last_ready_index_ + 1) % num_subchannels();
+ if (grpc_lb_round_robin_trace.enabled()) {
+ gpr_log(
+ GPR_INFO,
+ "[RR %p] checking subchannel %p, subchannel_list %p, index %" PRIuPTR
+ ": state=%s",
+ policy(), subchannel(index)->subchannel(), this, index,
+ grpc_connectivity_state_name(
+ subchannel(index)->connectivity_state()));
+ }
+ if (subchannel(index)->connectivity_state() == GRPC_CHANNEL_READY) {
+ if (grpc_lb_round_robin_trace.enabled()) {
+ gpr_log(GPR_INFO,
+ "[RR %p] found next ready subchannel (%p) at index %" PRIuPTR
+ " of subchannel_list %p",
+ policy(), subchannel(index)->subchannel(), index, this);
+ }
+ return index;
+ }
+ }
+ if (grpc_lb_round_robin_trace.enabled()) {
+ gpr_log(GPR_INFO, "[RR %p] no subchannels in ready state", this);
+ }
+ return num_subchannels();
+}
+
+// Sets last_ready_index_ to last_ready_index.
+void RoundRobin::RoundRobinSubchannelList::UpdateLastReadySubchannelIndexLocked(
+ size_t last_ready_index) {
+ GPR_ASSERT(last_ready_index < num_subchannels());
+ last_ready_index_ = last_ready_index;
+ if (grpc_lb_round_robin_trace.enabled()) {
+ gpr_log(GPR_INFO,
+ "[RR %p] setting last_ready_subchannel_index=%" PRIuPTR
+ " (SC %p, CSC %p)",
+ policy(), last_ready_index,
+ subchannel(last_ready_index)->subchannel(),
+ subchannel(last_ready_index)->connected_subchannel());
+ }
}
grpc_connectivity_state RoundRobin::CheckConnectivityLocked(
@@ -555,11 +592,12 @@
void RoundRobin::PingOneLocked(grpc_closure* on_initiate,
grpc_closure* on_ack) {
- const size_t next_ready_index = GetNextReadySubchannelIndexLocked();
- if (next_ready_index < subchannel_list_->num_subchannels) {
- grpc_lb_subchannel_data* selected =
- &subchannel_list_->subchannels[next_ready_index];
- selected->connected_subchannel->Ping(on_initiate, on_ack);
+ const size_t next_ready_index =
+ subchannel_list_->GetNextReadySubchannelIndexLocked();
+ if (next_ready_index < subchannel_list_->num_subchannels()) {
+ RoundRobinSubchannelData* selected =
+ subchannel_list_->subchannel(next_ready_index);
+ selected->connected_subchannel()->Ping(on_initiate, on_ack);
} else {
GRPC_CLOSURE_SCHED(on_initiate, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Round Robin not connected"));
@@ -582,80 +620,37 @@
}
return;
}
- grpc_lb_addresses* addresses = (grpc_lb_addresses*)arg->value.pointer.p;
+ grpc_lb_addresses* addresses =
+ static_cast<grpc_lb_addresses*>(arg->value.pointer.p);
if (grpc_lb_round_robin_trace.enabled()) {
- gpr_log(GPR_DEBUG, "[RR %p] received update with %" PRIuPTR " addresses",
+ gpr_log(GPR_INFO, "[RR %p] received update with %" PRIuPTR " addresses",
this, addresses->num_addresses);
}
- grpc_lb_subchannel_list* subchannel_list = grpc_lb_subchannel_list_create(
- this, &grpc_lb_round_robin_trace, addresses, combiner(),
- client_channel_factory(), args, &RoundRobin::OnConnectivityChangedLocked);
- if (subchannel_list->num_subchannels == 0) {
- grpc_connectivity_state_set(
- &state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE,
- GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"),
- "rr_update_empty");
- if (subchannel_list_ != nullptr) {
- grpc_lb_subchannel_list_shutdown_and_unref(subchannel_list_,
- "sl_shutdown_empty_update");
+ // Replace latest_pending_subchannel_list_.
+ if (latest_pending_subchannel_list_ != nullptr) {
+ if (grpc_lb_round_robin_trace.enabled()) {
+ gpr_log(GPR_INFO,
+ "[RR %p] Shutting down previous pending subchannel list %p", this,
+ latest_pending_subchannel_list_.get());
}
- subchannel_list_ = subchannel_list; // empty list
- return;
}
- if (started_picking_) {
- for (size_t i = 0; i < subchannel_list->num_subchannels; ++i) {
- const grpc_connectivity_state subchannel_state =
- grpc_subchannel_check_connectivity(
- subchannel_list->subchannels[i].subchannel, nullptr);
- // Override the default setting of IDLE for connectivity notification
- // purposes if the subchannel is already in transient failure. Otherwise
- // we'd be immediately notified of the IDLE-TRANSIENT_FAILURE
- // discrepancy, attempt to re-resolve and end up here again.
- // TODO(roth): As part of C++-ifying the subchannel_list API, design a
- // better API for notifying the LB policy of subchannel states, which can
- // be used both for the subchannel's initial state and for subsequent
- // state changes. This will allow us to handle this more generally instead
- // of special-casing TRANSIENT_FAILURE (e.g., we can also distribute any
- // pending picks across all READY subchannels rather than sending them all
- // to the first one).
- if (subchannel_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
- subchannel_list->subchannels[i].pending_connectivity_state_unsafe =
- subchannel_list->subchannels[i].curr_connectivity_state =
- subchannel_list->subchannels[i].prev_connectivity_state =
- subchannel_state;
- --subchannel_list->num_idle;
- ++subchannel_list->num_transient_failures;
- }
+ latest_pending_subchannel_list_ = MakeOrphanable<RoundRobinSubchannelList>(
+ this, &grpc_lb_round_robin_trace, addresses, combiner(),
+ client_channel_factory(), args);
+ // If we haven't started picking yet or the new list is empty,
+ // immediately promote the new list to the current list.
+ if (!started_picking_ ||
+ latest_pending_subchannel_list_->num_subchannels() == 0) {
+ if (latest_pending_subchannel_list_->num_subchannels() == 0) {
+ grpc_connectivity_state_set(
+ &state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE,
+ GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"),
+ "rr_update_empty");
}
- if (latest_pending_subchannel_list_ != nullptr) {
- if (grpc_lb_round_robin_trace.enabled()) {
- gpr_log(GPR_DEBUG,
- "[RR %p] Shutting down latest pending subchannel list %p, "
- "about to be replaced by newer latest %p",
- this, latest_pending_subchannel_list_, subchannel_list);
- }
- grpc_lb_subchannel_list_shutdown_and_unref(
- latest_pending_subchannel_list_, "sl_outdated");
- }
- latest_pending_subchannel_list_ = subchannel_list;
- for (size_t i = 0; i < subchannel_list->num_subchannels; ++i) {
- /* Watch every new subchannel. A subchannel list becomes active the
- * moment one of its subchannels is READY. At that moment, we swap
- * p->subchannel_list for sd->subchannel_list, provided the subchannel
- * list is still valid (ie, isn't shutting down) */
- SubchannelListRefForConnectivityWatch(subchannel_list,
- "connectivity_watch");
- grpc_lb_subchannel_data_start_connectivity_watch(
- &subchannel_list->subchannels[i]);
- }
+ subchannel_list_ = std::move(latest_pending_subchannel_list_);
} else {
- // The policy isn't picking yet. Save the update for later, disposing of
- // previous version if any.
- if (subchannel_list_ != nullptr) {
- grpc_lb_subchannel_list_shutdown_and_unref(
- subchannel_list_, "rr_update_before_started_picking");
- }
- subchannel_list_ = subchannel_list;
+ // If we've started picking, start watching the new list.
+ latest_pending_subchannel_list_->StartWatchingLocked();
}
}
diff --git a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc
deleted file mode 100644
index 79cb64c..0000000
--- a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- *
- * 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.
- *
- */
-
-#include <grpc/support/port_platform.h>
-
-#include <string.h>
-
-#include <grpc/support/alloc.h>
-
-#include "src/core/ext/filters/client_channel/lb_policy/subchannel_list.h"
-#include "src/core/lib/channel/channel_args.h"
-#include "src/core/lib/debug/trace.h"
-#include "src/core/lib/iomgr/closure.h"
-#include "src/core/lib/iomgr/combiner.h"
-#include "src/core/lib/iomgr/sockaddr_utils.h"
-#include "src/core/lib/transport/connectivity_state.h"
-
-void grpc_lb_subchannel_data_unref_subchannel(grpc_lb_subchannel_data* sd,
- const char* reason) {
- if (sd->subchannel != nullptr) {
- if (sd->subchannel_list->tracer->enabled()) {
- gpr_log(GPR_DEBUG,
- "[%s %p] subchannel list %p index %" PRIuPTR " of %" PRIuPTR
- " (subchannel %p): unreffing subchannel",
- sd->subchannel_list->tracer->name(), sd->subchannel_list->policy,
- sd->subchannel_list,
- static_cast<size_t>(sd - sd->subchannel_list->subchannels),
- sd->subchannel_list->num_subchannels, sd->subchannel);
- }
- GRPC_SUBCHANNEL_UNREF(sd->subchannel, reason);
- sd->subchannel = nullptr;
- sd->connected_subchannel.reset();
- if (sd->user_data != nullptr) {
- GPR_ASSERT(sd->user_data_vtable != nullptr);
- sd->user_data_vtable->destroy(sd->user_data);
- sd->user_data = nullptr;
- }
- }
-}
-
-void grpc_lb_subchannel_data_start_connectivity_watch(
- grpc_lb_subchannel_data* sd) {
- if (sd->subchannel_list->tracer->enabled()) {
- gpr_log(
- GPR_DEBUG,
- "[%s %p] subchannel list %p index %" PRIuPTR " of %" PRIuPTR
- " (subchannel %p): requesting connectivity change "
- "notification (from %s)",
- sd->subchannel_list->tracer->name(), sd->subchannel_list->policy,
- sd->subchannel_list,
- static_cast<size_t>(sd - sd->subchannel_list->subchannels),
- sd->subchannel_list->num_subchannels, sd->subchannel,
- grpc_connectivity_state_name(sd->pending_connectivity_state_unsafe));
- }
- sd->connectivity_notification_pending = true;
- grpc_subchannel_notify_on_state_change(
- sd->subchannel, sd->subchannel_list->policy->interested_parties(),
- &sd->pending_connectivity_state_unsafe,
- &sd->connectivity_changed_closure);
-}
-
-void grpc_lb_subchannel_data_stop_connectivity_watch(
- grpc_lb_subchannel_data* sd) {
- if (sd->subchannel_list->tracer->enabled()) {
- gpr_log(GPR_DEBUG,
- "[%s %p] subchannel list %p index %" PRIuPTR " of %" PRIuPTR
- " (subchannel %p): stopping connectivity watch",
- sd->subchannel_list->tracer->name(), sd->subchannel_list->policy,
- sd->subchannel_list,
- static_cast<size_t>(sd - sd->subchannel_list->subchannels),
- sd->subchannel_list->num_subchannels, sd->subchannel);
- }
- GPR_ASSERT(sd->connectivity_notification_pending);
- sd->connectivity_notification_pending = false;
-}
-
-grpc_lb_subchannel_list* grpc_lb_subchannel_list_create(
- grpc_core::LoadBalancingPolicy* p, grpc_core::TraceFlag* tracer,
- const grpc_lb_addresses* addresses, grpc_combiner* combiner,
- grpc_client_channel_factory* client_channel_factory,
- const grpc_channel_args& args, grpc_iomgr_cb_func connectivity_changed_cb) {
- grpc_lb_subchannel_list* subchannel_list =
- static_cast<grpc_lb_subchannel_list*>(
- gpr_zalloc(sizeof(*subchannel_list)));
- if (tracer->enabled()) {
- gpr_log(GPR_DEBUG,
- "[%s %p] Creating subchannel list %p for %" PRIuPTR " subchannels",
- tracer->name(), p, subchannel_list, addresses->num_addresses);
- }
- subchannel_list->policy = p;
- subchannel_list->tracer = tracer;
- gpr_ref_init(&subchannel_list->refcount, 1);
- subchannel_list->subchannels = static_cast<grpc_lb_subchannel_data*>(
- gpr_zalloc(sizeof(grpc_lb_subchannel_data) * addresses->num_addresses));
- // We need to remove the LB addresses in order to be able to compare the
- // subchannel keys of subchannels from a different batch of addresses.
- static const char* keys_to_remove[] = {GRPC_ARG_SUBCHANNEL_ADDRESS,
- GRPC_ARG_LB_ADDRESSES};
- // Create a subchannel for each address.
- grpc_subchannel_args sc_args;
- size_t subchannel_index = 0;
- for (size_t i = 0; i < addresses->num_addresses; i++) {
- // If there were any balancer, we would have chosen grpclb policy instead.
- GPR_ASSERT(!addresses->addresses[i].is_balancer);
- memset(&sc_args, 0, sizeof(grpc_subchannel_args));
- grpc_arg addr_arg =
- grpc_create_subchannel_address_arg(&addresses->addresses[i].address);
- grpc_channel_args* new_args = grpc_channel_args_copy_and_add_and_remove(
- &args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), &addr_arg, 1);
- gpr_free(addr_arg.value.string);
- sc_args.args = new_args;
- grpc_subchannel* subchannel = grpc_client_channel_factory_create_subchannel(
- client_channel_factory, &sc_args);
- grpc_channel_args_destroy(new_args);
- if (subchannel == nullptr) {
- // Subchannel could not be created.
- if (tracer->enabled()) {
- char* address_uri =
- grpc_sockaddr_to_uri(&addresses->addresses[i].address);
- gpr_log(GPR_DEBUG,
- "[%s %p] could not create subchannel for address uri %s, "
- "ignoring",
- tracer->name(), subchannel_list->policy, address_uri);
- gpr_free(address_uri);
- }
- continue;
- }
- if (tracer->enabled()) {
- char* address_uri =
- grpc_sockaddr_to_uri(&addresses->addresses[i].address);
- gpr_log(GPR_DEBUG,
- "[%s %p] subchannel list %p index %" PRIuPTR
- ": Created subchannel %p for address uri %s",
- tracer->name(), p, subchannel_list, subchannel_index, subchannel,
- address_uri);
- gpr_free(address_uri);
- }
- grpc_lb_subchannel_data* sd =
- &subchannel_list->subchannels[subchannel_index++];
- sd->subchannel_list = subchannel_list;
- sd->subchannel = subchannel;
- GRPC_CLOSURE_INIT(&sd->connectivity_changed_closure,
- connectivity_changed_cb, sd,
- grpc_combiner_scheduler(combiner));
- // We assume that the current state is IDLE. If not, we'll get a
- // callback telling us that.
- sd->prev_connectivity_state = GRPC_CHANNEL_IDLE;
- sd->curr_connectivity_state = GRPC_CHANNEL_IDLE;
- sd->pending_connectivity_state_unsafe = GRPC_CHANNEL_IDLE;
- sd->user_data_vtable = addresses->user_data_vtable;
- if (sd->user_data_vtable != nullptr) {
- sd->user_data =
- sd->user_data_vtable->copy(addresses->addresses[i].user_data);
- }
- }
- subchannel_list->num_subchannels = subchannel_index;
- subchannel_list->num_idle = subchannel_index;
- return subchannel_list;
-}
-
-static void subchannel_list_destroy(grpc_lb_subchannel_list* subchannel_list) {
- if (subchannel_list->tracer->enabled()) {
- gpr_log(GPR_DEBUG, "[%s %p] Destroying subchannel_list %p",
- subchannel_list->tracer->name(), subchannel_list->policy,
- subchannel_list);
- }
- for (size_t i = 0; i < subchannel_list->num_subchannels; i++) {
- grpc_lb_subchannel_data* sd = &subchannel_list->subchannels[i];
- grpc_lb_subchannel_data_unref_subchannel(sd, "subchannel_list_destroy");
- }
- gpr_free(subchannel_list->subchannels);
- gpr_free(subchannel_list);
-}
-
-void grpc_lb_subchannel_list_ref(grpc_lb_subchannel_list* subchannel_list,
- const char* reason) {
- gpr_ref_non_zero(&subchannel_list->refcount);
- if (subchannel_list->tracer->enabled()) {
- const gpr_atm count = gpr_atm_acq_load(&subchannel_list->refcount.count);
- gpr_log(GPR_DEBUG, "[%s %p] subchannel_list %p REF %lu->%lu (%s)",
- subchannel_list->tracer->name(), subchannel_list->policy,
- subchannel_list, static_cast<unsigned long>(count - 1),
- static_cast<unsigned long>(count), reason);
- }
-}
-
-void grpc_lb_subchannel_list_unref(grpc_lb_subchannel_list* subchannel_list,
- const char* reason) {
- const bool done = gpr_unref(&subchannel_list->refcount);
- if (subchannel_list->tracer->enabled()) {
- const gpr_atm count = gpr_atm_acq_load(&subchannel_list->refcount.count);
- gpr_log(GPR_DEBUG, "[%s %p] subchannel_list %p UNREF %lu->%lu (%s)",
- subchannel_list->tracer->name(), subchannel_list->policy,
- subchannel_list, static_cast<unsigned long>(count + 1),
- static_cast<unsigned long>(count), reason);
- }
- if (done) {
- subchannel_list_destroy(subchannel_list);
- }
-}
-
-static void subchannel_data_cancel_connectivity_watch(
- grpc_lb_subchannel_data* sd, const char* reason) {
- if (sd->subchannel_list->tracer->enabled()) {
- gpr_log(GPR_DEBUG,
- "[%s %p] subchannel list %p index %" PRIuPTR " of %" PRIuPTR
- " (subchannel %p): canceling connectivity watch (%s)",
- sd->subchannel_list->tracer->name(), sd->subchannel_list->policy,
- sd->subchannel_list,
- static_cast<size_t>(sd - sd->subchannel_list->subchannels),
- sd->subchannel_list->num_subchannels, sd->subchannel, reason);
- }
- grpc_subchannel_notify_on_state_change(sd->subchannel, nullptr, nullptr,
- &sd->connectivity_changed_closure);
-}
-
-void grpc_lb_subchannel_list_shutdown_and_unref(
- grpc_lb_subchannel_list* subchannel_list, const char* reason) {
- if (subchannel_list->tracer->enabled()) {
- gpr_log(GPR_DEBUG, "[%s %p] Shutting down subchannel_list %p (%s)",
- subchannel_list->tracer->name(), subchannel_list->policy,
- subchannel_list, reason);
- }
- GPR_ASSERT(!subchannel_list->shutting_down);
- subchannel_list->shutting_down = true;
- for (size_t i = 0; i < subchannel_list->num_subchannels; i++) {
- grpc_lb_subchannel_data* sd = &subchannel_list->subchannels[i];
- // If there's a pending notification for this subchannel, cancel it;
- // the callback is responsible for unreffing the subchannel.
- // Otherwise, unref the subchannel directly.
- if (sd->connectivity_notification_pending) {
- subchannel_data_cancel_connectivity_watch(sd, reason);
- } else if (sd->subchannel != nullptr) {
- grpc_lb_subchannel_data_unref_subchannel(sd, reason);
- }
- }
- grpc_lb_subchannel_list_unref(subchannel_list, reason);
-}
diff --git a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h
index 6889d59..7e2046b 100644
--- a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h
+++ b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h
@@ -21,116 +21,516 @@
#include <grpc/support/port_platform.h>
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+
#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
#include "src/core/ext/filters/client_channel/subchannel.h"
+#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/debug/trace.h"
+#include "src/core/lib/gprpp/abstract.h"
+#include "src/core/lib/gprpp/inlined_vector.h"
+#include "src/core/lib/gprpp/orphanable.h"
+#include "src/core/lib/gprpp/ref_counted.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
+#include "src/core/lib/iomgr/closure.h"
+#include "src/core/lib/iomgr/combiner.h"
+#include "src/core/lib/iomgr/sockaddr_utils.h"
#include "src/core/lib/transport/connectivity_state.h"
-// TODO(roth): This code is intended to be shared between pick_first and
-// round_robin. However, the interface needs more work to provide clean
-// encapsulation. For example, the structs here have some fields that are
-// only used in one of the two (e.g., the state counters in
-// grpc_lb_subchannel_list and the prev_connectivity_state field in
-// grpc_lb_subchannel_data are only used in round_robin, and the
-// checking_subchannel field in grpc_lb_subchannel_list is only used by
-// pick_first). Also, there is probably some code duplication between the
-// connectivity state notification callback code in both pick_first and
-// round_robin that could be refactored and moved here. In a future PR,
-// need to clean this up.
+// Code for maintaining a list of subchannels within an LB policy.
+//
+// To use this, callers must create their own subclasses, like so:
+/*
-typedef struct grpc_lb_subchannel_list grpc_lb_subchannel_list;
+class MySubchannelList; // Forward declaration.
-typedef struct {
- /** backpointer to owning subchannel list */
- grpc_lb_subchannel_list* subchannel_list;
- /** subchannel itself */
- grpc_subchannel* subchannel;
- grpc_core::RefCountedPtr<grpc_core::ConnectedSubchannel> connected_subchannel;
- /** Is a connectivity notification pending? */
- bool connectivity_notification_pending;
- /** notification that connectivity has changed on subchannel */
- grpc_closure connectivity_changed_closure;
- /** previous and current connectivity states. Updated by \a
- * \a connectivity_changed_closure based on
- * \a pending_connectivity_state_unsafe. */
- grpc_connectivity_state prev_connectivity_state;
- grpc_connectivity_state curr_connectivity_state;
- /** connectivity state to be updated by
- * grpc_subchannel_notify_on_state_change(), not guarded by
- * the combiner. To be copied to \a curr_connectivity_state by
- * \a connectivity_changed_closure. */
- grpc_connectivity_state pending_connectivity_state_unsafe;
- /** the subchannel's target user data */
- void* user_data;
- /** vtable to operate over \a user_data */
- const grpc_lb_user_data_vtable* user_data_vtable;
-} grpc_lb_subchannel_data;
-
-/// Unrefs the subchannel contained in sd.
-void grpc_lb_subchannel_data_unref_subchannel(grpc_lb_subchannel_data* sd,
- const char* reason);
-
-/// Starts watching the connectivity state of the subchannel.
-/// The connectivity_changed_cb callback must invoke either
-/// grpc_lb_subchannel_data_stop_connectivity_watch() or again call
-/// grpc_lb_subchannel_data_start_connectivity_watch().
-void grpc_lb_subchannel_data_start_connectivity_watch(
- grpc_lb_subchannel_data* sd);
-
-/// Stops watching the connectivity state of the subchannel.
-void grpc_lb_subchannel_data_stop_connectivity_watch(
- grpc_lb_subchannel_data* sd);
-
-struct grpc_lb_subchannel_list {
- /** backpointer to owning policy */
- grpc_core::LoadBalancingPolicy* policy;
-
- grpc_core::TraceFlag* tracer;
-
- /** all our subchannels */
- size_t num_subchannels;
- grpc_lb_subchannel_data* subchannels;
-
- /** Index into subchannels of the one we're currently checking.
- * Used when connecting to subchannels serially instead of in parallel. */
- // TODO(roth): When we have time, we can probably make this go away
- // and compute the index dynamically by subtracting
- // subchannel_list->subchannels from the subchannel_data pointer.
- size_t checking_subchannel;
-
- /** how many subchannels are in state READY */
- size_t num_ready;
- /** how many subchannels are in state TRANSIENT_FAILURE */
- size_t num_transient_failures;
- /** how many subchannels are in state IDLE */
- size_t num_idle;
-
- /** There will be one ref for each entry in subchannels for which there is a
- * pending connectivity state watcher callback. */
- gpr_refcount refcount;
-
- /** Is this list shutting down? This may be true due to the shutdown of the
- * policy itself or because a newer update has arrived while this one hadn't
- * finished processing. */
- bool shutting_down;
+class MySubchannelData
+ : public SubchannelData<MySubchannelList, MySubchannelData> {
+ public:
+ void ProcessConnectivityChangeLocked(
+ grpc_connectivity_state connectivity_state, grpc_error* error) override {
+ // ...code to handle connectivity changes...
+ }
};
-grpc_lb_subchannel_list* grpc_lb_subchannel_list_create(
- grpc_core::LoadBalancingPolicy* p, grpc_core::TraceFlag* tracer,
+class MySubchannelList
+ : public SubchannelList<MySubchannelList, MySubchannelData> {
+};
+
+*/
+// All methods with a Locked() suffix must be called from within the
+// client_channel combiner.
+
+namespace grpc_core {
+
+// Stores data for a particular subchannel in a subchannel list.
+// Callers must create a subclass that implements the
+// ProcessConnectivityChangeLocked() method.
+template <typename SubchannelListType, typename SubchannelDataType>
+class SubchannelData {
+ public:
+ // Returns a pointer to the subchannel list containing this object.
+ SubchannelListType* subchannel_list() const { return subchannel_list_; }
+
+ // Returns the index into the subchannel list of this object.
+ size_t Index() const {
+ return static_cast<size_t>(static_cast<const SubchannelDataType*>(this) -
+ subchannel_list_->subchannel(0));
+ }
+
+ // Returns a pointer to the subchannel.
+ grpc_subchannel* subchannel() const { return subchannel_; }
+
+ // Returns the connected subchannel. Will be null if the subchannel
+ // is not connected.
+ ConnectedSubchannel* connected_subchannel() const {
+ return connected_subchannel_.get();
+ }
+
+ // Synchronously checks the subchannel's connectivity state.
+ // Must not be called while there is a connectivity notification
+ // pending (i.e., between calling StartConnectivityWatchLocked() or
+ // RenewConnectivityWatchLocked() and the resulting invocation of
+ // ProcessConnectivityChangeLocked()).
+ grpc_connectivity_state CheckConnectivityStateLocked(grpc_error** error) {
+ GPR_ASSERT(!connectivity_notification_pending_);
+ pending_connectivity_state_unsafe_ =
+ grpc_subchannel_check_connectivity(subchannel(), error);
+ UpdateConnectedSubchannelLocked();
+ return pending_connectivity_state_unsafe_;
+ }
+
+ // Unrefs the subchannel. May be used if an individual subchannel is
+ // no longer needed even though the subchannel list as a whole is not
+ // being unreffed.
+ virtual void UnrefSubchannelLocked(const char* reason);
+
+ // Starts watching the connectivity state of the subchannel.
+ // ProcessConnectivityChangeLocked() will be called when the
+ // connectivity state changes.
+ void StartConnectivityWatchLocked();
+
+ // Renews watching the connectivity state of the subchannel.
+ void RenewConnectivityWatchLocked();
+
+ // Stops watching the connectivity state of the subchannel.
+ void StopConnectivityWatchLocked();
+
+ // Cancels watching the connectivity state of the subchannel.
+ // Must be called only while there is a connectivity notification
+ // pending (i.e., between calling StartConnectivityWatchLocked() or
+ // RenewConnectivityWatchLocked() and the resulting invocation of
+ // ProcessConnectivityChangeLocked()).
+ // From within ProcessConnectivityChangeLocked(), use
+ // StopConnectivityWatchLocked() instead.
+ void CancelConnectivityWatchLocked(const char* reason);
+
+ // Cancels any pending connectivity watch and unrefs the subchannel.
+ void ShutdownLocked();
+
+ GRPC_ABSTRACT_BASE_CLASS
+
+ protected:
+ SubchannelData(SubchannelListType* subchannel_list,
+ const grpc_lb_user_data_vtable* user_data_vtable,
+ const grpc_lb_address& address, grpc_subchannel* subchannel,
+ grpc_combiner* combiner);
+
+ virtual ~SubchannelData();
+
+ // After StartConnectivityWatchLocked() or RenewConnectivityWatchLocked()
+ // is called, this method will be invoked when the subchannel's connectivity
+ // state changes.
+ // Implementations must invoke either RenewConnectivityWatchLocked() or
+ // StopConnectivityWatchLocked() before returning.
+ virtual void ProcessConnectivityChangeLocked(
+ grpc_connectivity_state connectivity_state,
+ grpc_error* error) GRPC_ABSTRACT;
+
+ private:
+ // Updates connected_subchannel_ based on pending_connectivity_state_unsafe_.
+ // Returns true if the connectivity state should be reported.
+ bool UpdateConnectedSubchannelLocked();
+
+ static void OnConnectivityChangedLocked(void* arg, grpc_error* error);
+
+ // Backpointer to owning subchannel list. Not owned.
+ SubchannelListType* subchannel_list_;
+
+ // The subchannel and connected subchannel.
+ grpc_subchannel* subchannel_;
+ RefCountedPtr<ConnectedSubchannel> connected_subchannel_;
+
+ // Notification that connectivity has changed on subchannel.
+ grpc_closure connectivity_changed_closure_;
+ // Is a connectivity notification pending?
+ bool connectivity_notification_pending_ = false;
+ // Connectivity state to be updated by
+ // grpc_subchannel_notify_on_state_change(), not guarded by
+ // the combiner.
+ grpc_connectivity_state pending_connectivity_state_unsafe_;
+};
+
+// A list of subchannels.
+template <typename SubchannelListType, typename SubchannelDataType>
+class SubchannelList
+ : public InternallyRefCountedWithTracing<SubchannelListType> {
+ public:
+ typedef InlinedVector<SubchannelDataType, 10> SubchannelVector;
+
+ // The number of subchannels in the list.
+ size_t num_subchannels() const { return subchannels_.size(); }
+
+ // The data for the subchannel at a particular index.
+ SubchannelDataType* subchannel(size_t index) { return &subchannels_[index]; }
+
+ // Returns true if the subchannel list is shutting down.
+ bool shutting_down() const { return shutting_down_; }
+
+ // Accessors.
+ LoadBalancingPolicy* policy() const { return policy_; }
+ TraceFlag* tracer() const { return tracer_; }
+
+ // Note: Caller must ensure that this is invoked inside of the combiner.
+ void Orphan() override {
+ ShutdownLocked();
+ InternallyRefCountedWithTracing<SubchannelListType>::Unref(DEBUG_LOCATION,
+ "shutdown");
+ }
+
+ GRPC_ABSTRACT_BASE_CLASS
+
+ protected:
+ SubchannelList(LoadBalancingPolicy* policy, TraceFlag* tracer,
+ const grpc_lb_addresses* addresses, grpc_combiner* combiner,
+ grpc_client_channel_factory* client_channel_factory,
+ const grpc_channel_args& args);
+
+ virtual ~SubchannelList();
+
+ private:
+ // So New() can call our private ctor.
+ template <typename T, typename... Args>
+ friend T* New(Args&&... args);
+
+ // For accessing Ref() and Unref().
+ friend class SubchannelData<SubchannelListType, SubchannelDataType>;
+
+ void ShutdownLocked();
+
+ // Backpointer to owning policy.
+ LoadBalancingPolicy* policy_;
+
+ TraceFlag* tracer_;
+
+ grpc_combiner* combiner_;
+
+ // The list of subchannels.
+ SubchannelVector subchannels_;
+
+ // Is this list shutting down? This may be true due to the shutdown of the
+ // policy itself or because a newer update has arrived while this one hadn't
+ // finished processing.
+ bool shutting_down_ = false;
+};
+
+//
+// implementation -- no user-servicable parts below
+//
+
+//
+// SubchannelData
+//
+
+template <typename SubchannelListType, typename SubchannelDataType>
+SubchannelData<SubchannelListType, SubchannelDataType>::SubchannelData(
+ SubchannelListType* subchannel_list,
+ const grpc_lb_user_data_vtable* user_data_vtable,
+ const grpc_lb_address& address, grpc_subchannel* subchannel,
+ grpc_combiner* combiner)
+ : subchannel_list_(subchannel_list),
+ subchannel_(subchannel),
+ // We assume that the current state is IDLE. If not, we'll get a
+ // callback telling us that.
+ pending_connectivity_state_unsafe_(GRPC_CHANNEL_IDLE) {
+ GRPC_CLOSURE_INIT(
+ &connectivity_changed_closure_,
+ (&SubchannelData<SubchannelListType,
+ SubchannelDataType>::OnConnectivityChangedLocked),
+ this, grpc_combiner_scheduler(combiner));
+}
+
+template <typename SubchannelListType, typename SubchannelDataType>
+SubchannelData<SubchannelListType, SubchannelDataType>::~SubchannelData() {
+ UnrefSubchannelLocked("subchannel_data_destroy");
+}
+
+template <typename SubchannelListType, typename SubchannelDataType>
+void SubchannelData<SubchannelListType, SubchannelDataType>::
+ UnrefSubchannelLocked(const char* reason) {
+ if (subchannel_ != nullptr) {
+ if (subchannel_list_->tracer()->enabled()) {
+ gpr_log(GPR_INFO,
+ "[%s %p] subchannel list %p index %" PRIuPTR " of %" PRIuPTR
+ " (subchannel %p): unreffing subchannel",
+ subchannel_list_->tracer()->name(), subchannel_list_->policy(),
+ subchannel_list_, Index(), subchannel_list_->num_subchannels(),
+ subchannel_);
+ }
+ GRPC_SUBCHANNEL_UNREF(subchannel_, reason);
+ subchannel_ = nullptr;
+ connected_subchannel_.reset();
+ }
+}
+
+template <typename SubchannelListType, typename SubchannelDataType>
+void SubchannelData<SubchannelListType,
+ SubchannelDataType>::StartConnectivityWatchLocked() {
+ if (subchannel_list_->tracer()->enabled()) {
+ gpr_log(GPR_INFO,
+ "[%s %p] subchannel list %p index %" PRIuPTR " of %" PRIuPTR
+ " (subchannel %p): starting watch: requesting connectivity change "
+ "notification (from %s)",
+ subchannel_list_->tracer()->name(), subchannel_list_->policy(),
+ subchannel_list_, Index(), subchannel_list_->num_subchannels(),
+ subchannel_,
+ grpc_connectivity_state_name(pending_connectivity_state_unsafe_));
+ }
+ GPR_ASSERT(!connectivity_notification_pending_);
+ connectivity_notification_pending_ = true;
+ subchannel_list()->Ref(DEBUG_LOCATION, "connectivity_watch").release();
+ grpc_subchannel_notify_on_state_change(
+ subchannel_, subchannel_list_->policy()->interested_parties(),
+ &pending_connectivity_state_unsafe_, &connectivity_changed_closure_);
+}
+
+template <typename SubchannelListType, typename SubchannelDataType>
+void SubchannelData<SubchannelListType,
+ SubchannelDataType>::RenewConnectivityWatchLocked() {
+ if (subchannel_list_->tracer()->enabled()) {
+ gpr_log(GPR_INFO,
+ "[%s %p] subchannel list %p index %" PRIuPTR " of %" PRIuPTR
+ " (subchannel %p): renewing watch: requesting connectivity change "
+ "notification (from %s)",
+ subchannel_list_->tracer()->name(), subchannel_list_->policy(),
+ subchannel_list_, Index(), subchannel_list_->num_subchannels(),
+ subchannel_,
+ grpc_connectivity_state_name(pending_connectivity_state_unsafe_));
+ }
+ GPR_ASSERT(connectivity_notification_pending_);
+ grpc_subchannel_notify_on_state_change(
+ subchannel_, subchannel_list_->policy()->interested_parties(),
+ &pending_connectivity_state_unsafe_, &connectivity_changed_closure_);
+}
+
+template <typename SubchannelListType, typename SubchannelDataType>
+void SubchannelData<SubchannelListType,
+ SubchannelDataType>::StopConnectivityWatchLocked() {
+ if (subchannel_list_->tracer()->enabled()) {
+ gpr_log(GPR_INFO,
+ "[%s %p] subchannel list %p index %" PRIuPTR " of %" PRIuPTR
+ " (subchannel %p): stopping connectivity watch",
+ subchannel_list_->tracer()->name(), subchannel_list_->policy(),
+ subchannel_list_, Index(), subchannel_list_->num_subchannels(),
+ subchannel_);
+ }
+ GPR_ASSERT(connectivity_notification_pending_);
+ connectivity_notification_pending_ = false;
+ subchannel_list()->Unref(DEBUG_LOCATION, "connectivity_watch");
+}
+
+template <typename SubchannelListType, typename SubchannelDataType>
+void SubchannelData<SubchannelListType, SubchannelDataType>::
+ CancelConnectivityWatchLocked(const char* reason) {
+ if (subchannel_list_->tracer()->enabled()) {
+ gpr_log(GPR_INFO,
+ "[%s %p] subchannel list %p index %" PRIuPTR " of %" PRIuPTR
+ " (subchannel %p): canceling connectivity watch (%s)",
+ subchannel_list_->tracer()->name(), subchannel_list_->policy(),
+ subchannel_list_, Index(), subchannel_list_->num_subchannels(),
+ subchannel_, reason);
+ }
+ GPR_ASSERT(connectivity_notification_pending_);
+ grpc_subchannel_notify_on_state_change(subchannel_, nullptr, nullptr,
+ &connectivity_changed_closure_);
+}
+
+template <typename SubchannelListType, typename SubchannelDataType>
+bool SubchannelData<SubchannelListType,
+ SubchannelDataType>::UpdateConnectedSubchannelLocked() {
+ // If the subchannel is READY, take a ref to the connected subchannel.
+ if (pending_connectivity_state_unsafe_ == GRPC_CHANNEL_READY) {
+ connected_subchannel_ =
+ grpc_subchannel_get_connected_subchannel(subchannel_);
+ // If the subchannel became disconnected between the time that READY
+ // was reported and the time we got here (e.g., between when a
+ // notification callback is scheduled and when it was actually run in
+ // the combiner), then the connected subchannel may have disappeared out
+ // from under us. In that case, we don't actually want to consider the
+ // subchannel to be in state READY. Instead, we use IDLE as the
+ // basis for any future connectivity watch; this is the one state that
+ // the subchannel will never transition back into, so this ensures
+ // that we will get a notification for the next state, even if that state
+ // is READY again (e.g., if the subchannel has transitioned back to
+ // READY before the next watch gets requested).
+ if (connected_subchannel_ == nullptr) {
+ if (subchannel_list_->tracer()->enabled()) {
+ gpr_log(GPR_INFO,
+ "[%s %p] subchannel list %p index %" PRIuPTR " of %" PRIuPTR
+ " (subchannel %p): state is READY but connected subchannel is "
+ "null; moving to state IDLE",
+ subchannel_list_->tracer()->name(), subchannel_list_->policy(),
+ subchannel_list_, Index(), subchannel_list_->num_subchannels(),
+ subchannel_);
+ }
+ pending_connectivity_state_unsafe_ = GRPC_CHANNEL_IDLE;
+ return false;
+ }
+ } else {
+ // For any state other than READY, unref the connected subchannel.
+ connected_subchannel_.reset();
+ }
+ return true;
+}
+
+template <typename SubchannelListType, typename SubchannelDataType>
+void SubchannelData<SubchannelListType, SubchannelDataType>::
+ OnConnectivityChangedLocked(void* arg, grpc_error* error) {
+ SubchannelData* sd = static_cast<SubchannelData*>(arg);
+ if (sd->subchannel_list_->tracer()->enabled()) {
+ gpr_log(
+ GPR_INFO,
+ "[%s %p] subchannel list %p index %" PRIuPTR " of %" PRIuPTR
+ " (subchannel %p): connectivity changed: state=%s, error=%s, "
+ "shutting_down=%d",
+ sd->subchannel_list_->tracer()->name(), sd->subchannel_list_->policy(),
+ sd->subchannel_list_, sd->Index(),
+ sd->subchannel_list_->num_subchannels(), sd->subchannel_,
+ grpc_connectivity_state_name(sd->pending_connectivity_state_unsafe_),
+ grpc_error_string(error), sd->subchannel_list_->shutting_down());
+ }
+ // If shutting down, unref subchannel and stop watching.
+ if (sd->subchannel_list_->shutting_down() || error == GRPC_ERROR_CANCELLED) {
+ sd->UnrefSubchannelLocked("connectivity_shutdown");
+ sd->StopConnectivityWatchLocked();
+ return;
+ }
+ // Get or release ref to connected subchannel.
+ if (!sd->UpdateConnectedSubchannelLocked()) {
+ // We don't want to report this connectivity state, so renew the watch.
+ sd->RenewConnectivityWatchLocked();
+ return;
+ }
+ // Call the subclass's ProcessConnectivityChangeLocked() method.
+ sd->ProcessConnectivityChangeLocked(sd->pending_connectivity_state_unsafe_,
+ GRPC_ERROR_REF(error));
+}
+
+template <typename SubchannelListType, typename SubchannelDataType>
+void SubchannelData<SubchannelListType, SubchannelDataType>::ShutdownLocked() {
+ // If there's a pending notification for this subchannel, cancel it;
+ // the callback is responsible for unreffing the subchannel.
+ // Otherwise, unref the subchannel directly.
+ if (connectivity_notification_pending_) {
+ CancelConnectivityWatchLocked("shutdown");
+ } else if (subchannel_ != nullptr) {
+ UnrefSubchannelLocked("shutdown");
+ }
+}
+
+//
+// SubchannelList
+//
+
+template <typename SubchannelListType, typename SubchannelDataType>
+SubchannelList<SubchannelListType, SubchannelDataType>::SubchannelList(
+ LoadBalancingPolicy* policy, TraceFlag* tracer,
const grpc_lb_addresses* addresses, grpc_combiner* combiner,
grpc_client_channel_factory* client_channel_factory,
- const grpc_channel_args& args, grpc_iomgr_cb_func connectivity_changed_cb);
+ const grpc_channel_args& args)
+ : InternallyRefCountedWithTracing<SubchannelListType>(tracer),
+ policy_(policy),
+ tracer_(tracer),
+ combiner_(GRPC_COMBINER_REF(combiner, "subchannel_list")) {
+ if (tracer_->enabled()) {
+ gpr_log(GPR_INFO,
+ "[%s %p] Creating subchannel list %p for %" PRIuPTR " subchannels",
+ tracer_->name(), policy, this, addresses->num_addresses);
+ }
+ subchannels_.reserve(addresses->num_addresses);
+ // We need to remove the LB addresses in order to be able to compare the
+ // subchannel keys of subchannels from a different batch of addresses.
+ static const char* keys_to_remove[] = {GRPC_ARG_SUBCHANNEL_ADDRESS,
+ GRPC_ARG_LB_ADDRESSES};
+ // Create a subchannel for each address.
+ grpc_subchannel_args sc_args;
+ for (size_t i = 0; i < addresses->num_addresses; i++) {
+ // If there were any balancer, we would have chosen grpclb policy instead.
+ GPR_ASSERT(!addresses->addresses[i].is_balancer);
+ memset(&sc_args, 0, sizeof(grpc_subchannel_args));
+ grpc_arg addr_arg =
+ grpc_create_subchannel_address_arg(&addresses->addresses[i].address);
+ grpc_channel_args* new_args = grpc_channel_args_copy_and_add_and_remove(
+ &args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), &addr_arg, 1);
+ gpr_free(addr_arg.value.string);
+ sc_args.args = new_args;
+ grpc_subchannel* subchannel = grpc_client_channel_factory_create_subchannel(
+ client_channel_factory, &sc_args);
+ grpc_channel_args_destroy(new_args);
+ if (subchannel == nullptr) {
+ // Subchannel could not be created.
+ if (tracer_->enabled()) {
+ char* address_uri =
+ grpc_sockaddr_to_uri(&addresses->addresses[i].address);
+ gpr_log(GPR_INFO,
+ "[%s %p] could not create subchannel for address uri %s, "
+ "ignoring",
+ tracer_->name(), policy_, address_uri);
+ gpr_free(address_uri);
+ }
+ continue;
+ }
+ if (tracer_->enabled()) {
+ char* address_uri =
+ grpc_sockaddr_to_uri(&addresses->addresses[i].address);
+ gpr_log(GPR_INFO,
+ "[%s %p] subchannel list %p index %" PRIuPTR
+ ": Created subchannel %p for address uri %s",
+ tracer_->name(), policy_, this, subchannels_.size(), subchannel,
+ address_uri);
+ gpr_free(address_uri);
+ }
+ subchannels_.emplace_back(static_cast<SubchannelListType*>(this),
+ addresses->user_data_vtable,
+ addresses->addresses[i], subchannel, combiner);
+ }
+}
-void grpc_lb_subchannel_list_ref(grpc_lb_subchannel_list* subchannel_list,
- const char* reason);
+template <typename SubchannelListType, typename SubchannelDataType>
+SubchannelList<SubchannelListType, SubchannelDataType>::~SubchannelList() {
+ if (tracer_->enabled()) {
+ gpr_log(GPR_INFO, "[%s %p] Destroying subchannel_list %p", tracer_->name(),
+ policy_, this);
+ }
+ GRPC_COMBINER_UNREF(combiner_, "subchannel_list");
+}
-void grpc_lb_subchannel_list_unref(grpc_lb_subchannel_list* subchannel_list,
- const char* reason);
+template <typename SubchannelListType, typename SubchannelDataType>
+void SubchannelList<SubchannelListType, SubchannelDataType>::ShutdownLocked() {
+ if (tracer_->enabled()) {
+ gpr_log(GPR_INFO, "[%s %p] Shutting down subchannel_list %p",
+ tracer_->name(), policy_, this);
+ }
+ GPR_ASSERT(!shutting_down_);
+ shutting_down_ = true;
+ for (size_t i = 0; i < subchannels_.size(); i++) {
+ SubchannelDataType* sd = &subchannels_[i];
+ sd->ShutdownLocked();
+ }
+}
-/// Mark subchannel_list as discarded. Unsubscribes all its subchannels. The
-/// connectivity state notification callback will ultimately unref it.
-void grpc_lb_subchannel_list_shutdown_and_unref(
- grpc_lb_subchannel_list* subchannel_list, const char* reason);
+} // namespace grpc_core
#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_SUBCHANNEL_LIST_H */
diff --git a/src/core/ext/filters/client_channel/method_params.h b/src/core/ext/filters/client_channel/method_params.h
index 099924e..a31d360 100644
--- a/src/core/ext/filters/client_channel/method_params.h
+++ b/src/core/ext/filters/client_channel/method_params.h
@@ -60,6 +60,10 @@
template <typename T, typename... Args>
friend T* grpc_core::New(Args&&... args);
+ // So Delete() can call our private dtor.
+ template <typename T>
+ friend void grpc_core::Delete(T*);
+
ClientChannelMethodParams() {}
virtual ~ClientChannelMethodParams() {}
diff --git a/src/core/ext/filters/client_channel/resolver.h b/src/core/ext/filters/client_channel/resolver.h
index cdb5a20..0238031 100644
--- a/src/core/ext/filters/client_channel/resolver.h
+++ b/src/core/ext/filters/client_channel/resolver.h
@@ -105,6 +105,10 @@
GRPC_ABSTRACT_BASE_CLASS
protected:
+ // So Delete() can access our protected dtor.
+ template <typename T>
+ friend void Delete(T*);
+
/// Does NOT take ownership of the reference to \a combiner.
// TODO(roth): Once we have a C++-like interface for combiners, this
// API should change to take a RefCountedPtr<>, so that we always take
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
index aca7307..c3c62b6 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
@@ -135,6 +135,7 @@
if (path[0] == '/') ++path;
name_to_resolve_ = gpr_strdup(path);
// Get DNS server from URI authority.
+ dns_server_ = nullptr;
if (0 != strcmp(args.uri->authority, "")) {
dns_server_ = gpr_strdup(args.uri->authority);
}
@@ -362,6 +363,15 @@
}
void AresDnsResolver::MaybeStartResolvingLocked() {
+ // If there is an existing timer, the time it fires is the earliest time we
+ // can start the next resolution.
+ if (have_next_resolution_timer_) {
+ // TODO(dgq): remove the following two lines once Pick First stops
+ // discarding subchannels after selecting.
+ ++resolved_version_;
+ MaybeFinishNextLocked();
+ return;
+ }
if (last_resolution_timestamp_ >= 0) {
const grpc_millis earliest_next_resolution =
last_resolution_timestamp_ + min_time_between_resolutions_;
@@ -374,17 +384,15 @@
"In cooldown from last resolution (from %" PRIdPTR
" ms ago). Will resolve again in %" PRIdPTR " ms",
last_resolution_ago, ms_until_next_resolution);
- if (!have_next_resolution_timer_) {
- have_next_resolution_timer_ = true;
- // TODO(roth): We currently deal with this ref manually. Once the
- // new closure API is done, find a way to track this ref with the timer
- // callback as part of the type system.
- RefCountedPtr<Resolver> self =
- Ref(DEBUG_LOCATION, "next_resolution_timer_cooldown");
- self.release();
- grpc_timer_init(&next_resolution_timer_, ms_until_next_resolution,
- &on_next_resolution_);
- }
+ have_next_resolution_timer_ = true;
+ // TODO(roth): We currently deal with this ref manually. Once the
+ // new closure API is done, find a way to track this ref with the timer
+ // callback as part of the type system.
+ RefCountedPtr<Resolver> self =
+ Ref(DEBUG_LOCATION, "next_resolution_timer_cooldown");
+ self.release();
+ grpc_timer_init(&next_resolution_timer_, ms_until_next_resolution,
+ &on_next_resolution_);
// TODO(dgq): remove the following two lines once Pick First stops
// discarding subchannels after selecting.
++resolved_version_;
@@ -396,6 +404,7 @@
}
void AresDnsResolver::StartResolvingLocked() {
+ gpr_log(GPR_DEBUG, "Start resolving.");
// TODO(roth): We currently deal with this ref manually. Once the
// new closure API is done, find a way to track this ref with the timer
// callback as part of the type system.
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
index fb24357..e86ab5a 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
@@ -153,7 +153,10 @@
/* If there are no pending queries, invoke on_done callback and destroy the
request */
if (gpr_unref(&r->pending_queries)) {
- grpc_cares_wrapper_address_sorting_sort(*(r->lb_addrs_out));
+ grpc_lb_addresses* lb_addrs = *(r->lb_addrs_out);
+ if (lb_addrs != nullptr) {
+ grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ }
GRPC_CLOSURE_SCHED(r->on_done, r->error);
gpr_mu_destroy(&r->mu);
grpc_ares_ev_driver_destroy(r->ev_driver);
diff --git a/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc b/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc
index fbab136..e7842a7 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc
+++ b/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc
@@ -236,6 +236,15 @@
}
void NativeDnsResolver::MaybeStartResolvingLocked() {
+ // If there is an existing timer, the time it fires is the earliest time we
+ // can start the next resolution.
+ if (have_next_resolution_timer_) {
+ // TODO(dgq): remove the following two lines once Pick First stops
+ // discarding subchannels after selecting.
+ ++resolved_version_;
+ MaybeFinishNextLocked();
+ return;
+ }
if (last_resolution_timestamp_ >= 0) {
const grpc_millis earliest_next_resolution =
last_resolution_timestamp_ + min_time_between_resolutions_;
@@ -248,17 +257,15 @@
"In cooldown from last resolution (from %" PRIdPTR
" ms ago). Will resolve again in %" PRIdPTR " ms",
last_resolution_ago, ms_until_next_resolution);
- if (!have_next_resolution_timer_) {
- have_next_resolution_timer_ = true;
- // TODO(roth): We currently deal with this ref manually. Once the
- // new closure API is done, find a way to track this ref with the timer
- // callback as part of the type system.
- RefCountedPtr<Resolver> self =
- Ref(DEBUG_LOCATION, "next_resolution_timer_cooldown");
- self.release();
- grpc_timer_init(&next_resolution_timer_, ms_until_next_resolution,
- &on_next_resolution_);
- }
+ have_next_resolution_timer_ = true;
+ // TODO(roth): We currently deal with this ref manually. Once the
+ // new closure API is done, find a way to track this ref with the timer
+ // callback as part of the type system.
+ RefCountedPtr<Resolver> self =
+ Ref(DEBUG_LOCATION, "next_resolution_timer_cooldown");
+ self.release();
+ grpc_timer_init(&next_resolution_timer_, ms_until_next_resolution,
+ &on_next_resolution_);
// TODO(dgq): remove the following two lines once Pick First stops
// discarding subchannels after selecting.
++resolved_version_;
@@ -270,6 +277,7 @@
}
void NativeDnsResolver::StartResolvingLocked() {
+ gpr_log(GPR_DEBUG, "Start resolving.");
// TODO(roth): We currently deal with this ref manually. Once the
// new closure API is done, find a way to track this ref with the timer
// callback as part of the type system.
diff --git a/src/core/ext/filters/client_channel/retry_throttle.cc b/src/core/ext/filters/client_channel/retry_throttle.cc
index 45de666..bdeb7e4 100644
--- a/src/core/ext/filters/client_channel/retry_throttle.cc
+++ b/src/core/ext/filters/client_channel/retry_throttle.cc
@@ -30,184 +30,162 @@
#include "src/core/lib/avl/avl.h"
+namespace grpc_core {
+namespace internal {
+
//
-// server_retry_throttle_data
+// ServerRetryThrottleData
//
-struct grpc_server_retry_throttle_data {
- gpr_refcount refs;
- int max_milli_tokens;
- int milli_token_ratio;
- gpr_atm milli_tokens;
- // A pointer to the replacement for this grpc_server_retry_throttle_data
- // entry. If non-nullptr, then this entry is stale and must not be used.
- // We hold a reference to the replacement.
- gpr_atm replacement;
-};
-
-static void get_replacement_throttle_data_if_needed(
- grpc_server_retry_throttle_data** throttle_data) {
- while (true) {
- grpc_server_retry_throttle_data* new_throttle_data =
- (grpc_server_retry_throttle_data*)gpr_atm_acq_load(
- &(*throttle_data)->replacement);
- if (new_throttle_data == nullptr) return;
- *throttle_data = new_throttle_data;
- }
-}
-
-bool grpc_server_retry_throttle_data_record_failure(
- grpc_server_retry_throttle_data* throttle_data) {
- if (throttle_data == nullptr) return true;
- // First, check if we are stale and need to be replaced.
- get_replacement_throttle_data_if_needed(&throttle_data);
- // We decrement milli_tokens by 1000 (1 token) for each failure.
- const int new_value = static_cast<int>(gpr_atm_no_barrier_clamped_add(
- &throttle_data->milli_tokens, static_cast<gpr_atm>(-1000),
- static_cast<gpr_atm>(0),
- static_cast<gpr_atm>(throttle_data->max_milli_tokens)));
- // Retries are allowed as long as the new value is above the threshold
- // (max_milli_tokens / 2).
- return new_value > throttle_data->max_milli_tokens / 2;
-}
-
-void grpc_server_retry_throttle_data_record_success(
- grpc_server_retry_throttle_data* throttle_data) {
- if (throttle_data == nullptr) return;
- // First, check if we are stale and need to be replaced.
- get_replacement_throttle_data_if_needed(&throttle_data);
- // We increment milli_tokens by milli_token_ratio for each success.
- gpr_atm_no_barrier_clamped_add(
- &throttle_data->milli_tokens,
- static_cast<gpr_atm>(throttle_data->milli_token_ratio),
- static_cast<gpr_atm>(0),
- static_cast<gpr_atm>(throttle_data->max_milli_tokens));
-}
-
-grpc_server_retry_throttle_data* grpc_server_retry_throttle_data_ref(
- grpc_server_retry_throttle_data* throttle_data) {
- gpr_ref(&throttle_data->refs);
- return throttle_data;
-}
-
-void grpc_server_retry_throttle_data_unref(
- grpc_server_retry_throttle_data* throttle_data) {
- if (gpr_unref(&throttle_data->refs)) {
- grpc_server_retry_throttle_data* replacement =
- (grpc_server_retry_throttle_data*)gpr_atm_acq_load(
- &throttle_data->replacement);
- if (replacement != nullptr) {
- grpc_server_retry_throttle_data_unref(replacement);
- }
- gpr_free(throttle_data);
- }
-}
-
-static grpc_server_retry_throttle_data* grpc_server_retry_throttle_data_create(
- int max_milli_tokens, int milli_token_ratio,
- grpc_server_retry_throttle_data* old_throttle_data) {
- grpc_server_retry_throttle_data* throttle_data =
- static_cast<grpc_server_retry_throttle_data*>(
- gpr_malloc(sizeof(*throttle_data)));
- memset(throttle_data, 0, sizeof(*throttle_data));
- gpr_ref_init(&throttle_data->refs, 1);
- throttle_data->max_milli_tokens = max_milli_tokens;
- throttle_data->milli_token_ratio = milli_token_ratio;
- int initial_milli_tokens = max_milli_tokens;
+ServerRetryThrottleData::ServerRetryThrottleData(
+ intptr_t max_milli_tokens, intptr_t milli_token_ratio,
+ ServerRetryThrottleData* old_throttle_data)
+ : max_milli_tokens_(max_milli_tokens),
+ milli_token_ratio_(milli_token_ratio) {
+ intptr_t initial_milli_tokens = max_milli_tokens;
// If there was a pre-existing entry for this server name, initialize
// the token count by scaling proportionately to the old data. This
// ensures that if we're already throttling retries on the old scale,
// we will start out doing the same thing on the new one.
if (old_throttle_data != nullptr) {
double token_fraction =
- static_cast<int>(gpr_atm_acq_load(&old_throttle_data->milli_tokens)) /
- static_cast<double>(old_throttle_data->max_milli_tokens);
- initial_milli_tokens = static_cast<int>(token_fraction * max_milli_tokens);
+ static_cast<intptr_t>(
+ gpr_atm_acq_load(&old_throttle_data->milli_tokens_)) /
+ static_cast<double>(old_throttle_data->max_milli_tokens_);
+ initial_milli_tokens =
+ static_cast<intptr_t>(token_fraction * max_milli_tokens);
}
- gpr_atm_rel_store(&throttle_data->milli_tokens,
- (gpr_atm)initial_milli_tokens);
+ gpr_atm_rel_store(&milli_tokens_, static_cast<gpr_atm>(initial_milli_tokens));
// If there was a pre-existing entry, mark it as stale and give it a
// pointer to the new entry, which is its replacement.
if (old_throttle_data != nullptr) {
- grpc_server_retry_throttle_data_ref(throttle_data);
- gpr_atm_rel_store(&old_throttle_data->replacement, (gpr_atm)throttle_data);
+ Ref().release(); // Ref held by pre-existing entry.
+ gpr_atm_rel_store(&old_throttle_data->replacement_,
+ reinterpret_cast<gpr_atm>(this));
}
- return throttle_data;
+}
+
+ServerRetryThrottleData::~ServerRetryThrottleData() {
+ ServerRetryThrottleData* replacement =
+ reinterpret_cast<ServerRetryThrottleData*>(
+ gpr_atm_acq_load(&replacement_));
+ if (replacement != nullptr) {
+ replacement->Unref();
+ }
+}
+
+void ServerRetryThrottleData::GetReplacementThrottleDataIfNeeded(
+ ServerRetryThrottleData** throttle_data) {
+ while (true) {
+ ServerRetryThrottleData* new_throttle_data =
+ reinterpret_cast<ServerRetryThrottleData*>(
+ gpr_atm_acq_load(&(*throttle_data)->replacement_));
+ if (new_throttle_data == nullptr) return;
+ *throttle_data = new_throttle_data;
+ }
+}
+
+bool ServerRetryThrottleData::RecordFailure() {
+ // First, check if we are stale and need to be replaced.
+ ServerRetryThrottleData* throttle_data = this;
+ GetReplacementThrottleDataIfNeeded(&throttle_data);
+ // We decrement milli_tokens by 1000 (1 token) for each failure.
+ const intptr_t new_value =
+ static_cast<intptr_t>(gpr_atm_no_barrier_clamped_add(
+ &throttle_data->milli_tokens_, static_cast<gpr_atm>(-1000),
+ static_cast<gpr_atm>(0),
+ static_cast<gpr_atm>(throttle_data->max_milli_tokens_)));
+ // Retries are allowed as long as the new value is above the threshold
+ // (max_milli_tokens / 2).
+ return new_value > throttle_data->max_milli_tokens_ / 2;
+}
+
+void ServerRetryThrottleData::RecordSuccess() {
+ // First, check if we are stale and need to be replaced.
+ ServerRetryThrottleData* throttle_data = this;
+ GetReplacementThrottleDataIfNeeded(&throttle_data);
+ // We increment milli_tokens by milli_token_ratio for each success.
+ gpr_atm_no_barrier_clamped_add(
+ &throttle_data->milli_tokens_,
+ static_cast<gpr_atm>(throttle_data->milli_token_ratio_),
+ static_cast<gpr_atm>(0),
+ static_cast<gpr_atm>(throttle_data->max_milli_tokens_));
}
//
// avl vtable for string -> server_retry_throttle_data map
//
-static void* copy_server_name(void* key, void* unused) {
+namespace {
+
+void* copy_server_name(void* key, void* unused) {
return gpr_strdup(static_cast<const char*>(key));
}
-static long compare_server_name(void* key1, void* key2, void* unused) {
+long compare_server_name(void* key1, void* key2, void* unused) {
return strcmp(static_cast<const char*>(key1), static_cast<const char*>(key2));
}
-static void destroy_server_retry_throttle_data(void* value, void* unused) {
- grpc_server_retry_throttle_data* throttle_data =
- static_cast<grpc_server_retry_throttle_data*>(value);
- grpc_server_retry_throttle_data_unref(throttle_data);
+void destroy_server_retry_throttle_data(void* value, void* unused) {
+ ServerRetryThrottleData* throttle_data =
+ static_cast<ServerRetryThrottleData*>(value);
+ throttle_data->Unref();
}
-static void* copy_server_retry_throttle_data(void* value, void* unused) {
- grpc_server_retry_throttle_data* throttle_data =
- static_cast<grpc_server_retry_throttle_data*>(value);
- return grpc_server_retry_throttle_data_ref(throttle_data);
+void* copy_server_retry_throttle_data(void* value, void* unused) {
+ ServerRetryThrottleData* throttle_data =
+ static_cast<ServerRetryThrottleData*>(value);
+ return throttle_data->Ref().release();
}
-static void destroy_server_name(void* key, void* unused) { gpr_free(key); }
+void destroy_server_name(void* key, void* unused) { gpr_free(key); }
-static const grpc_avl_vtable avl_vtable = {
+const grpc_avl_vtable avl_vtable = {
destroy_server_name, copy_server_name, compare_server_name,
destroy_server_retry_throttle_data, copy_server_retry_throttle_data};
+} // namespace
+
//
-// server_retry_throttle_map
+// ServerRetryThrottleMap
//
static gpr_mu g_mu;
static grpc_avl g_avl;
-void grpc_retry_throttle_map_init() {
+void ServerRetryThrottleMap::Init() {
gpr_mu_init(&g_mu);
g_avl = grpc_avl_create(&avl_vtable);
}
-void grpc_retry_throttle_map_shutdown() {
+void ServerRetryThrottleMap::Shutdown() {
gpr_mu_destroy(&g_mu);
grpc_avl_unref(g_avl, nullptr);
}
-grpc_server_retry_throttle_data* grpc_retry_throttle_map_get_data_for_server(
- const char* server_name, int max_milli_tokens, int milli_token_ratio) {
+RefCountedPtr<ServerRetryThrottleData> ServerRetryThrottleMap::GetDataForServer(
+ const char* server_name, intptr_t max_milli_tokens,
+ intptr_t milli_token_ratio) {
+ RefCountedPtr<ServerRetryThrottleData> result;
gpr_mu_lock(&g_mu);
- grpc_server_retry_throttle_data* throttle_data =
- static_cast<grpc_server_retry_throttle_data*>(
+ ServerRetryThrottleData* throttle_data =
+ static_cast<ServerRetryThrottleData*>(
grpc_avl_get(g_avl, const_cast<char*>(server_name), nullptr));
- if (throttle_data == nullptr) {
- // Entry not found. Create a new one.
- throttle_data = grpc_server_retry_throttle_data_create(
- max_milli_tokens, milli_token_ratio, nullptr);
- g_avl = grpc_avl_add(g_avl, const_cast<char*>(server_name), throttle_data,
- nullptr);
+ if (throttle_data == nullptr ||
+ throttle_data->max_milli_tokens() != max_milli_tokens ||
+ throttle_data->milli_token_ratio() != milli_token_ratio) {
+ // Entry not found, or found with old parameters. Create a new one.
+ result = MakeRefCounted<ServerRetryThrottleData>(
+ max_milli_tokens, milli_token_ratio, throttle_data);
+ g_avl = grpc_avl_add(g_avl, gpr_strdup(server_name),
+ result->Ref().release(), nullptr);
} else {
- if (throttle_data->max_milli_tokens != max_milli_tokens ||
- throttle_data->milli_token_ratio != milli_token_ratio) {
- // Entry found but with old parameters. Create a new one based on
- // the original one.
- throttle_data = grpc_server_retry_throttle_data_create(
- max_milli_tokens, milli_token_ratio, throttle_data);
- g_avl = grpc_avl_add(g_avl, const_cast<char*>(server_name), throttle_data,
- nullptr);
- } else {
- // Entry found. Increase refcount.
- grpc_server_retry_throttle_data_ref(throttle_data);
- }
+ // Entry found. Return a new ref to it.
+ result = throttle_data->Ref();
}
gpr_mu_unlock(&g_mu);
- return throttle_data;
+ return result;
}
+
+} // namespace internal
+} // namespace grpc_core
diff --git a/src/core/ext/filters/client_channel/retry_throttle.h b/src/core/ext/filters/client_channel/retry_throttle.h
index 0505fc2..fddafcd 100644
--- a/src/core/ext/filters/client_channel/retry_throttle.h
+++ b/src/core/ext/filters/client_channel/retry_throttle.h
@@ -21,32 +21,61 @@
#include <grpc/support/port_platform.h>
-#include <stdbool.h>
+#include "src/core/lib/gprpp/ref_counted.h"
+
+namespace grpc_core {
+namespace internal {
/// Tracks retry throttling data for an individual server name.
-typedef struct grpc_server_retry_throttle_data grpc_server_retry_throttle_data;
+class ServerRetryThrottleData : public RefCounted<ServerRetryThrottleData> {
+ public:
+ ServerRetryThrottleData(intptr_t max_milli_tokens, intptr_t milli_token_ratio,
+ ServerRetryThrottleData* old_throttle_data);
-/// Records a failure. Returns true if it's okay to send a retry.
-bool grpc_server_retry_throttle_data_record_failure(
- grpc_server_retry_throttle_data* throttle_data);
-/// Records a success.
-void grpc_server_retry_throttle_data_record_success(
- grpc_server_retry_throttle_data* throttle_data);
+ /// Records a failure. Returns true if it's okay to send a retry.
+ bool RecordFailure();
-grpc_server_retry_throttle_data* grpc_server_retry_throttle_data_ref(
- grpc_server_retry_throttle_data* throttle_data);
-void grpc_server_retry_throttle_data_unref(
- grpc_server_retry_throttle_data* throttle_data);
+ /// Records a success.
+ void RecordSuccess();
-/// Initializes global map of failure data for each server name.
-void grpc_retry_throttle_map_init();
-/// Shuts down global map of failure data for each server name.
-void grpc_retry_throttle_map_shutdown();
+ intptr_t max_milli_tokens() const { return max_milli_tokens_; }
+ intptr_t milli_token_ratio() const { return milli_token_ratio_; }
-/// Returns a reference to the failure data for \a server_name, creating
-/// a new entry if needed.
-/// Caller must eventually unref via \a grpc_server_retry_throttle_data_unref().
-grpc_server_retry_throttle_data* grpc_retry_throttle_map_get_data_for_server(
- const char* server_name, int max_milli_tokens, int milli_token_ratio);
+ private:
+ // So Delete() can call our private dtor.
+ template <typename T>
+ friend void grpc_core::Delete(T*);
+
+ ~ServerRetryThrottleData();
+
+ void GetReplacementThrottleDataIfNeeded(
+ ServerRetryThrottleData** throttle_data);
+
+ const intptr_t max_milli_tokens_;
+ const intptr_t milli_token_ratio_;
+ gpr_atm milli_tokens_;
+ // A pointer to the replacement for this ServerRetryThrottleData entry.
+ // If non-nullptr, then this entry is stale and must not be used.
+ // We hold a reference to the replacement.
+ gpr_atm replacement_ = 0;
+};
+
+/// Global map of server name to retry throttle data.
+class ServerRetryThrottleMap {
+ public:
+ /// Initializes global map of failure data for each server name.
+ static void Init();
+ /// Shuts down global map of failure data for each server name.
+ static void Shutdown();
+
+ /// Returns the failure data for \a server_name, creating a new entry if
+ /// needed.
+ static RefCountedPtr<ServerRetryThrottleData> GetDataForServer(
+ const char* server_name, intptr_t max_milli_tokens,
+ intptr_t milli_token_ratio);
+};
+
+} // namespace internal
+} // namespace grpc_core
#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RETRY_THROTTLE_H */
diff --git a/src/core/ext/filters/http/client_authority_filter.cc b/src/core/ext/filters/http/client_authority_filter.cc
new file mode 100644
index 0000000..1f57ab5
--- /dev/null
+++ b/src/core/ext/filters/http/client_authority_filter.cc
@@ -0,0 +1,156 @@
+/*
+ *
+ * Copyright 2018 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.
+ *
+ */
+
+#include <grpc/support/port_platform.h>
+
+#include <assert.h>
+#include <limits.h>
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+
+#include "src/core/ext/filters/http/client_authority_filter.h"
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/slice/slice_internal.h"
+#include "src/core/lib/slice/slice_string_helpers.h"
+#include "src/core/lib/surface/call.h"
+#include "src/core/lib/surface/channel_init.h"
+#include "src/core/lib/surface/channel_stack_type.h"
+#include "src/core/lib/transport/static_metadata.h"
+
+namespace {
+
+struct call_data {
+ grpc_linked_mdelem authority_storage;
+ grpc_call_combiner* call_combiner;
+};
+
+struct channel_data {
+ grpc_slice default_authority;
+};
+
+void authority_start_transport_stream_op_batch(
+ grpc_call_element* elem, grpc_transport_stream_op_batch* batch) {
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
+ call_data* calld = static_cast<call_data*>(elem->call_data);
+ // Handle send_initial_metadata.
+ auto* initial_metadata =
+ batch->payload->send_initial_metadata.send_initial_metadata;
+ // If the initial metadata doesn't already contain :authority, add it.
+ if (batch->send_initial_metadata &&
+ initial_metadata->idx.named.authority == nullptr) {
+ grpc_error* error = grpc_metadata_batch_add_head(
+ initial_metadata, &calld->authority_storage,
+ grpc_mdelem_from_slices(GRPC_MDSTR_AUTHORITY,
+ grpc_slice_ref(chand->default_authority)));
+ if (error != GRPC_ERROR_NONE) {
+ grpc_transport_stream_op_batch_finish_with_failure(batch, error,
+ calld->call_combiner);
+ return;
+ }
+ }
+ // Pass control down the stack.
+ grpc_call_next_op(elem, batch);
+}
+
+/* Constructor for call_data */
+grpc_error* init_call_elem(grpc_call_element* elem,
+ const grpc_call_element_args* args) {
+ call_data* calld = static_cast<call_data*>(elem->call_data);
+ calld->call_combiner = args->call_combiner;
+ return GRPC_ERROR_NONE;
+}
+
+/* Destructor for call_data */
+void destroy_call_elem(grpc_call_element* elem,
+ const grpc_call_final_info* final_info,
+ grpc_closure* ignored) {}
+
+/* Constructor for channel_data */
+grpc_error* init_channel_elem(grpc_channel_element* elem,
+ grpc_channel_element_args* args) {
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
+ const grpc_arg* default_authority_arg =
+ grpc_channel_args_find(args->channel_args, GRPC_ARG_DEFAULT_AUTHORITY);
+ if (default_authority_arg == nullptr) {
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+ "GRPC_ARG_DEFAULT_AUTHORITY channel arg. not found. Note that direct "
+ "channels must explicity specify a value for this argument.");
+ }
+ const char* default_authority_str =
+ grpc_channel_arg_get_string(default_authority_arg);
+ if (default_authority_str == nullptr) {
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+ "GRPC_ARG_DEFAULT_AUTHORITY channel arg. must be a string");
+ }
+ chand->default_authority =
+ grpc_slice_from_copied_string(default_authority_str);
+ GPR_ASSERT(!args->is_last);
+ return GRPC_ERROR_NONE;
+}
+
+/* Destructor for channel data */
+void destroy_channel_elem(grpc_channel_element* elem) {
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
+ grpc_slice_unref(chand->default_authority);
+}
+} // namespace
+
+const grpc_channel_filter grpc_client_authority_filter = {
+ authority_start_transport_stream_op_batch,
+ grpc_channel_next_op,
+ sizeof(call_data),
+ init_call_elem,
+ grpc_call_stack_ignore_set_pollset_or_pollset_set,
+ destroy_call_elem,
+ sizeof(channel_data),
+ init_channel_elem,
+ destroy_channel_elem,
+ grpc_channel_next_get_info,
+ "authority"};
+
+static bool add_client_authority_filter(grpc_channel_stack_builder* builder,
+ void* arg) {
+ const grpc_channel_args* channel_args =
+ grpc_channel_stack_builder_get_channel_arguments(builder);
+ const grpc_arg* disable_client_authority_filter_arg = grpc_channel_args_find(
+ channel_args, GRPC_ARG_DISABLE_CLIENT_AUTHORITY_FILTER);
+ if (disable_client_authority_filter_arg != nullptr) {
+ const bool is_client_authority_filter_disabled =
+ grpc_channel_arg_get_bool(disable_client_authority_filter_arg, false);
+ if (is_client_authority_filter_disabled) {
+ return true;
+ }
+ }
+ return grpc_channel_stack_builder_prepend_filter(
+ builder, static_cast<const grpc_channel_filter*>(arg), nullptr, nullptr);
+}
+
+void grpc_client_authority_filter_init(void) {
+ grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL, INT_MAX,
+ add_client_authority_filter,
+ (void*)&grpc_client_authority_filter);
+ grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL, INT_MAX,
+ add_client_authority_filter,
+ (void*)&grpc_client_authority_filter);
+}
+
+void grpc_client_authority_filter_shutdown(void) {}
diff --git a/src/core/ext/filters/http/client_authority_filter.h b/src/core/ext/filters/http/client_authority_filter.h
new file mode 100644
index 0000000..5824e91
--- /dev/null
+++ b/src/core/ext/filters/http/client_authority_filter.h
@@ -0,0 +1,34 @@
+/*
+ *
+ * Copyright 2018 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_EXT_FILTERS_HTTP_CLIENT_AUTHORITY_FILTER_H
+#define GRPC_CORE_EXT_FILTERS_HTTP_CLIENT_AUTHORITY_FILTER_H
+
+#include <grpc/support/port_platform.h>
+
+#include <grpc/impl/codegen/compression_types.h>
+
+#include "src/core/lib/channel/channel_stack.h"
+
+/// Filter responsible for setting the authority header, if not already set. It
+/// uses the value of the GRPC_ARG_DEFAULT_AUTHORITY channel arg if the initial
+/// metadata doesn't already contain an authority value.
+
+extern const grpc_channel_filter grpc_client_authority_filter;
+
+#endif /* GRPC_CORE_EXT_FILTERS_HTTP_CLIENT_AUTHORITY_FILTER_H */
diff --git a/src/core/ext/filters/http/message_compress/message_compress_filter.cc b/src/core/ext/filters/http/message_compress/message_compress_filter.cc
index e7d9949..f8f478b 100644
--- a/src/core/ext/filters/http/message_compress/message_compress_filter.cc
+++ b/src/core/ext/filters/http/message_compress/message_compress_filter.cc
@@ -234,7 +234,7 @@
static_cast<float>(before_size);
GPR_ASSERT(grpc_message_compression_algorithm_name(
calld->message_compression_algorithm, &algo_name));
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"Compressed[%s] %" PRIuPTR " bytes vs. %" PRIuPTR
" bytes (%.2f%% savings)",
algo_name, before_size, after_size, 100 * savings_ratio);
@@ -246,7 +246,7 @@
const char* algo_name;
GPR_ASSERT(grpc_message_compression_algorithm_name(
calld->message_compression_algorithm, &algo_name));
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"Algorithm '%s' enabled but decided not to compress. Input size: "
"%" PRIuPTR,
algo_name, calld->slices.length);
diff --git a/src/core/ext/transport/chttp2/client/authority.cc b/src/core/ext/transport/chttp2/client/authority.cc
new file mode 100644
index 0000000..bad3153
--- /dev/null
+++ b/src/core/ext/transport/chttp2/client/authority.cc
@@ -0,0 +1,42 @@
+/*
+ *
+ * Copyright 2018 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.
+ *
+ */
+
+#include <grpc/support/port_platform.h>
+
+#include "src/core/ext/transport/chttp2/client/authority.h"
+
+grpc_channel_args* grpc_default_authority_add_if_not_present(
+ const grpc_channel_args* args) {
+ const bool has_default_authority =
+ grpc_channel_args_find(args, GRPC_ARG_DEFAULT_AUTHORITY) != nullptr;
+ grpc_arg new_args[1];
+ size_t num_new_args = 0;
+ grpc_core::UniquePtr<char> default_authority;
+ if (!has_default_authority) {
+ const grpc_arg* server_uri_arg =
+ grpc_channel_args_find(args, GRPC_ARG_SERVER_URI);
+ const char* server_uri_str = grpc_channel_arg_get_string(server_uri_arg);
+ GPR_ASSERT(server_uri_str != nullptr);
+ default_authority =
+ grpc_core::ResolverRegistry::GetDefaultAuthority(server_uri_str);
+ GPR_ASSERT(default_authority != nullptr);
+ new_args[num_new_args++] = grpc_channel_arg_string_create(
+ const_cast<char*>(GRPC_ARG_DEFAULT_AUTHORITY), default_authority.get());
+ }
+ return grpc_channel_args_copy_and_add(args, new_args, num_new_args);
+}
diff --git a/src/core/ext/transport/chttp2/client/authority.h b/src/core/ext/transport/chttp2/client/authority.h
new file mode 100644
index 0000000..642584e
--- /dev/null
+++ b/src/core/ext/transport/chttp2/client/authority.h
@@ -0,0 +1,36 @@
+/*
+ *
+ * Copyright 2018 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_EXT_TRANSPORT_CHTTP2_CLIENT_AUTHORITY_H
+#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_CLIENT_AUTHORITY_H
+
+#include <grpc/support/port_platform.h>
+
+#include <grpc/grpc.h>
+
+#include "src/core/ext/filters/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/resolver_registry.h"
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gprpp/memory.h"
+
+/// Returns a copy of \a args with the default authority channel arg set if it
+/// wasn't already present.
+grpc_channel_args* grpc_default_authority_add_if_not_present(
+ const grpc_channel_args* args);
+
+#endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_CLIENT_AUTHORITY_H */
diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create.cc b/src/core/ext/transport/chttp2/client/insecure/channel_create.cc
index 6080036..e6c8c38 100644
--- a/src/core/ext/transport/chttp2/client/insecure/channel_create.cc
+++ b/src/core/ext/transport/chttp2/client/insecure/channel_create.cc
@@ -27,6 +27,7 @@
#include "src/core/ext/filters/client_channel/client_channel.h"
#include "src/core/ext/filters/client_channel/resolver_registry.h"
+#include "src/core/ext/transport/chttp2/client/authority.h"
#include "src/core/ext/transport/chttp2/client/chttp2_connector.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/surface/api_trace.h"
@@ -40,9 +41,13 @@
static grpc_subchannel* client_channel_factory_create_subchannel(
grpc_client_channel_factory* cc_factory, const grpc_subchannel_args* args) {
+ grpc_subchannel_args final_sc_args;
+ memcpy(&final_sc_args, args, sizeof(*args));
+ final_sc_args.args = grpc_default_authority_add_if_not_present(args->args);
grpc_connector* connector = grpc_chttp2_connector_create();
- grpc_subchannel* s = grpc_subchannel_create(connector, args);
+ grpc_subchannel* s = grpc_subchannel_create(connector, &final_sc_args);
grpc_connector_unref(connector);
+ grpc_channel_args_destroy(const_cast<grpc_channel_args*>(final_sc_args.args));
return s;
}
@@ -56,8 +61,8 @@
// Add channel arg containing the server URI.
grpc_core::UniquePtr<char> canonical_target =
grpc_core::ResolverRegistry::AddDefaultPrefixIfNeeded(target);
- grpc_arg arg = grpc_channel_arg_string_create((char*)GRPC_ARG_SERVER_URI,
- canonical_target.get());
+ grpc_arg arg = grpc_channel_arg_string_create(
+ const_cast<char*>(GRPC_ARG_SERVER_URI), canonical_target.get());
const char* to_remove[] = {GRPC_ARG_SERVER_URI};
grpc_channel_args* new_args =
grpc_channel_args_copy_and_add_and_remove(args, to_remove, 1, &arg, 1);
diff --git a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc
index a82009f..5ce73a9 100644
--- a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc
+++ b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc
@@ -71,9 +71,6 @@
grpc_uri* server_uri =
grpc_uri_parse(server_uri_str, true /* supress errors */);
GPR_ASSERT(server_uri != nullptr);
- const char* server_uri_path;
- server_uri_path =
- server_uri->path[0] == '/' ? server_uri->path + 1 : server_uri->path;
const grpc_core::TargetAuthorityTable* target_authority_table =
grpc_core::FindTargetAuthorityTableInArgs(args->args);
grpc_core::UniquePtr<char> authority;
@@ -98,33 +95,49 @@
// authority table was present or because the target was not present
// in the table), fall back to using the original server URI.
if (authority == nullptr) {
- authority.reset(gpr_strdup(server_uri_path));
+ authority =
+ grpc_core::ResolverRegistry::GetDefaultAuthority(server_uri_str);
}
+ grpc_arg args_to_add[2];
+ size_t num_args_to_add = 0;
+ if (grpc_channel_args_find(args->args, GRPC_ARG_DEFAULT_AUTHORITY) ==
+ nullptr) {
+ // If the channel args don't already contain GRPC_ARG_DEFAULT_AUTHORITY, add
+ // the arg, setting it to the value just obtained.
+ args_to_add[num_args_to_add++] = grpc_channel_arg_string_create(
+ const_cast<char*>(GRPC_ARG_DEFAULT_AUTHORITY), authority.get());
+ }
+ grpc_channel_args* args_with_authority =
+ grpc_channel_args_copy_and_add(args->args, args_to_add, num_args_to_add);
grpc_uri_destroy(server_uri);
grpc_channel_security_connector* subchannel_security_connector = nullptr;
// Create the security connector using the credentials and target name.
grpc_channel_args* new_args_from_connector = nullptr;
const grpc_security_status security_status =
grpc_channel_credentials_create_security_connector(
- channel_credentials, authority.get(), args->args,
+ channel_credentials, authority.get(), args_with_authority,
&subchannel_security_connector, &new_args_from_connector);
if (security_status != GRPC_SECURITY_OK) {
gpr_log(GPR_ERROR,
"Failed to create secure subchannel for secure name '%s'",
authority.get());
+ grpc_channel_args_destroy(args_with_authority);
return nullptr;
}
grpc_arg new_security_connector_arg =
grpc_security_connector_to_arg(&subchannel_security_connector->base);
grpc_channel_args* new_args = grpc_channel_args_copy_and_add(
- new_args_from_connector != nullptr ? new_args_from_connector : args->args,
+ new_args_from_connector != nullptr ? new_args_from_connector
+ : args_with_authority,
&new_security_connector_arg, 1);
+
GRPC_SECURITY_CONNECTOR_UNREF(&subchannel_security_connector->base,
"lb_channel_create");
if (new_args_from_connector != nullptr) {
grpc_channel_args_destroy(new_args_from_connector);
}
+ grpc_channel_args_destroy(args_with_authority);
grpc_subchannel_args* final_sc_args =
static_cast<grpc_subchannel_args*>(gpr_malloc(sizeof(*final_sc_args)));
memcpy(final_sc_args, args, sizeof(*args));
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc
index dc4e002..0ef7396 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc
+++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc
@@ -807,7 +807,7 @@
static void set_write_state(grpc_chttp2_transport* t,
grpc_chttp2_write_state st, const char* reason) {
- GRPC_CHTTP2_IF_TRACING(gpr_log(GPR_DEBUG, "W:%p %s state %s -> %s [%s]", t,
+ GRPC_CHTTP2_IF_TRACING(gpr_log(GPR_INFO, "W:%p %s state %s -> %s [%s]", t,
t->is_client ? "CLIENT" : "SERVER",
write_state_name(t->write_state),
write_state_name(st), reason));
@@ -1072,7 +1072,7 @@
uint32_t goaway_error,
grpc_slice goaway_text) {
// GRPC_CHTTP2_IF_TRACING(
- // gpr_log(GPR_DEBUG, "got goaway [%d]: %s", goaway_error, msg));
+ // gpr_log(GPR_INFO, "got goaway [%d]: %s", goaway_error, msg));
// Discard the error from a previous goaway frame (if any)
if (t->goaway_error != GRPC_ERROR_NONE) {
@@ -1118,7 +1118,7 @@
grpc_chttp2_list_pop_waiting_for_concurrency(t, &s)) {
/* safe since we can't (legally) be parsing this stream yet */
GRPC_CHTTP2_IF_TRACING(gpr_log(
- GPR_DEBUG, "HTTP:%s: Allocating new grpc_chttp2_stream %p to id %d",
+ GPR_INFO, "HTTP:%s: Allocating new grpc_chttp2_stream %p to id %d",
t->is_client ? "CLI" : "SVR", s, t->next_stream_id));
GPR_ASSERT(s->id == 0);
@@ -1183,7 +1183,7 @@
if (grpc_http_trace.enabled()) {
const char* errstr = grpc_error_string(error);
gpr_log(
- GPR_DEBUG,
+ GPR_INFO,
"complete_closure_step: t=%p %p refs=%d flags=0x%04x desc=%s err=%s "
"write_state=%s",
t, closure,
@@ -1336,7 +1336,7 @@
if (grpc_http_trace.enabled()) {
char* str = grpc_transport_stream_op_batch_string(op);
- gpr_log(GPR_DEBUG, "perform_stream_op_locked: %s; on_complete = %p", str,
+ gpr_log(GPR_INFO, "perform_stream_op_locked: %s; on_complete = %p", str,
op->on_complete);
gpr_free(str);
if (op->send_initial_metadata) {
@@ -1638,7 +1638,7 @@
if (grpc_http_trace.enabled()) {
char* str = grpc_transport_stream_op_batch_string(op);
- gpr_log(GPR_DEBUG, "perform_stream_op[s=%p]: %s", s, str);
+ gpr_log(GPR_INFO, "perform_stream_op[s=%p]: %s", s, str);
gpr_free(str);
}
@@ -1676,6 +1676,33 @@
GRPC_ERROR_NONE);
}
+/*
+ * Specialized form of send_ping_locked for keepalive ping. If there is already
+ * a ping in progress, the keepalive ping would piggyback onto that ping,
+ * instead of waiting for that ping to complete and then starting a new ping.
+ */
+static void send_keepalive_ping_locked(grpc_chttp2_transport* t) {
+ if (t->closed_with_error != GRPC_ERROR_NONE) {
+ GRPC_CLOSURE_SCHED(&t->start_keepalive_ping_locked,
+ GRPC_ERROR_REF(t->closed_with_error));
+ GRPC_CLOSURE_SCHED(&t->finish_keepalive_ping_locked,
+ GRPC_ERROR_REF(t->closed_with_error));
+ return;
+ }
+ grpc_chttp2_ping_queue* pq = &t->ping_queue;
+ if (!grpc_closure_list_empty(pq->lists[GRPC_CHTTP2_PCL_INFLIGHT])) {
+ /* There is a ping in flight. Add yourself to the inflight closure list. */
+ GRPC_CLOSURE_SCHED(&t->start_keepalive_ping_locked, GRPC_ERROR_NONE);
+ grpc_closure_list_append(&pq->lists[GRPC_CHTTP2_PCL_INFLIGHT],
+ &t->finish_keepalive_ping_locked, GRPC_ERROR_NONE);
+ return;
+ }
+ grpc_closure_list_append(&pq->lists[GRPC_CHTTP2_PCL_INITIATE],
+ &t->start_keepalive_ping_locked, GRPC_ERROR_NONE);
+ grpc_closure_list_append(&pq->lists[GRPC_CHTTP2_PCL_NEXT],
+ &t->finish_keepalive_ping_locked, GRPC_ERROR_NONE);
+}
+
static void retry_initiate_ping_locked(void* tp, grpc_error* error) {
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(tp);
t->ping_state.is_delayed_ping_timer_set = false;
@@ -2502,7 +2529,7 @@
static void start_bdp_ping_locked(void* tp, grpc_error* error) {
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(tp);
if (grpc_http_trace.enabled()) {
- gpr_log(GPR_DEBUG, "%s: Start BDP ping err=%s", t->peer_string,
+ gpr_log(GPR_INFO, "%s: Start BDP ping err=%s", t->peer_string,
grpc_error_string(error));
}
/* Reset the keepalive ping timer */
@@ -2515,7 +2542,7 @@
static void finish_bdp_ping_locked(void* tp, grpc_error* error) {
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(tp);
if (grpc_http_trace.enabled()) {
- gpr_log(GPR_DEBUG, "%s: Complete BDP ping err=%s", t->peer_string,
+ gpr_log(GPR_INFO, "%s: Complete BDP ping err=%s", t->peer_string,
grpc_error_string(error));
}
if (error != GRPC_ERROR_NONE) {
@@ -2619,8 +2646,7 @@
grpc_chttp2_stream_map_size(&t->stream_map) > 0) {
t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_PINGING;
GRPC_CHTTP2_REF_TRANSPORT(t, "keepalive ping end");
- send_ping_locked(t, &t->start_keepalive_ping_locked,
- &t->finish_keepalive_ping_locked);
+ send_keepalive_ping_locked(t);
grpc_chttp2_initiate_write(t, GRPC_CHTTP2_INITIATE_WRITE_KEEPALIVE_PING);
} else {
GRPC_CHTTP2_REF_TRANSPORT(t, "init keepalive ping");
@@ -2690,8 +2716,7 @@
static void connectivity_state_set(grpc_chttp2_transport* t,
grpc_connectivity_state state,
grpc_error* error, const char* reason) {
- GRPC_CHTTP2_IF_TRACING(
- gpr_log(GPR_DEBUG, "set connectivity_state=%d", state));
+ GRPC_CHTTP2_IF_TRACING(gpr_log(GPR_INFO, "set connectivity_state=%d", state));
grpc_connectivity_state_set(&t->channel_callback.state_tracker, state, error,
reason);
}
@@ -2958,7 +2983,7 @@
/* Channel with no active streams: send a goaway to try and make it
* disconnect cleanly */
if (grpc_resource_quota_trace.enabled()) {
- gpr_log(GPR_DEBUG, "HTTP2: %s - send goaway to free memory",
+ gpr_log(GPR_INFO, "HTTP2: %s - send goaway to free memory",
t->peer_string);
}
send_goaway(t,
@@ -2966,7 +2991,7 @@
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Buffers full"),
GRPC_ERROR_INT_HTTP2_ERROR, GRPC_HTTP2_ENHANCE_YOUR_CALM));
} else if (error == GRPC_ERROR_NONE && grpc_resource_quota_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"HTTP2: %s - skip benign reclamation, there are still %" PRIdPTR
" streams",
t->peer_string, grpc_chttp2_stream_map_size(&t->stream_map));
@@ -2987,7 +3012,7 @@
grpc_chttp2_stream* s = static_cast<grpc_chttp2_stream*>(
grpc_chttp2_stream_map_rand(&t->stream_map));
if (grpc_resource_quota_trace.enabled()) {
- gpr_log(GPR_DEBUG, "HTTP2: %s - abandon stream id %d", t->peer_string,
+ gpr_log(GPR_INFO, "HTTP2: %s - abandon stream id %d", t->peer_string,
s->id);
}
grpc_chttp2_cancel_stream(
diff --git a/src/core/ext/transport/chttp2/transport/frame_settings.cc b/src/core/ext/transport/chttp2/transport/frame_settings.cc
index 9ea27dc..987ac0e 100644
--- a/src/core/ext/transport/chttp2/transport/frame_settings.cc
+++ b/src/core/ext/transport/chttp2/transport/frame_settings.cc
@@ -217,14 +217,14 @@
t->initial_window_update += static_cast<int64_t>(parser->value) -
parser->incoming_settings[id];
if (grpc_http_trace.enabled() || grpc_flowctl_trace.enabled()) {
- gpr_log(GPR_DEBUG, "%p[%s] adding %d for initial_window change",
- t, t->is_client ? "cli" : "svr",
+ gpr_log(GPR_INFO, "%p[%s] adding %d for initial_window change", t,
+ t->is_client ? "cli" : "svr",
static_cast<int>(t->initial_window_update));
}
}
parser->incoming_settings[id] = parser->value;
if (grpc_http_trace.enabled()) {
- gpr_log(GPR_DEBUG, "CHTTP2:%s:%s: got setting %s = %d",
+ gpr_log(GPR_INFO, "CHTTP2:%s:%s: got setting %s = %d",
t->is_client ? "CLI" : "SVR", t->peer_string, sp->name,
parser->value);
}
diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc
index e4f3c1b..d5ef063 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc
+++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc
@@ -470,7 +470,7 @@
v = grpc_slice_to_c_string(GRPC_MDVALUE(elem));
}
gpr_log(
- GPR_DEBUG,
+ GPR_INFO,
"Encode: '%s: %s', elem_interned=%d [%d], k_interned=%d, v_interned=%d",
k, v, GRPC_MDELEM_IS_INTERNED(elem), GRPC_MDELEM_STORAGE(elem),
grpc_slice_is_interned(GRPC_MDKEY(elem)),
@@ -654,7 +654,7 @@
}
c->advertise_table_size_change = 1;
if (grpc_http_trace.enabled()) {
- gpr_log(GPR_DEBUG, "set max table size from encoder to %d", max_table_size);
+ gpr_log(GPR_INFO, "set max table size from encoder to %d", max_table_size);
}
}
diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.cc b/src/core/ext/transport/chttp2/transport/hpack_parser.cc
index fc96a8b..907ba71 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_parser.cc
+++ b/src/core/ext/transport/chttp2/transport/hpack_parser.cc
@@ -633,7 +633,7 @@
v = grpc_slice_to_c_string(GRPC_MDVALUE(md));
}
gpr_log(
- GPR_DEBUG,
+ GPR_INFO,
"Decode: '%s: %s', elem_interned=%d [%d], k_interned=%d, v_interned=%d",
k, v, GRPC_MDELEM_IS_INTERNED(md), GRPC_MDELEM_STORAGE(md),
grpc_slice_is_interned(GRPC_MDKEY(md)),
diff --git a/src/core/ext/transport/chttp2/transport/hpack_table.cc b/src/core/ext/transport/chttp2/transport/hpack_table.cc
index f050f50..7929258 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_table.cc
+++ b/src/core/ext/transport/chttp2/transport/hpack_table.cc
@@ -247,7 +247,7 @@
return;
}
if (grpc_http_trace.enabled()) {
- gpr_log(GPR_DEBUG, "Update hpack parser max size to %d", max_bytes);
+ gpr_log(GPR_INFO, "Update hpack parser max size to %d", max_bytes);
}
while (tbl->mem_used > max_bytes) {
evict1(tbl);
@@ -270,7 +270,7 @@
return err;
}
if (grpc_http_trace.enabled()) {
- gpr_log(GPR_DEBUG, "Update hpack parser table size to %d", bytes);
+ gpr_log(GPR_INFO, "Update hpack parser table size to %d", bytes);
}
while (tbl->mem_used > bytes) {
evict1(tbl);
diff --git a/src/core/ext/transport/chttp2/transport/stream_lists.cc b/src/core/ext/transport/chttp2/transport/stream_lists.cc
index 5d3ec4b..6626170 100644
--- a/src/core/ext/transport/chttp2/transport/stream_lists.cc
+++ b/src/core/ext/transport/chttp2/transport/stream_lists.cc
@@ -68,7 +68,7 @@
}
*stream = s;
if (s && grpc_trace_http2_stream_state.enabled()) {
- gpr_log(GPR_DEBUG, "%p[%d][%s]: pop from %s", t, s->id,
+ gpr_log(GPR_INFO, "%p[%d][%s]: pop from %s", t, s->id,
t->is_client ? "cli" : "svr", stream_list_id_string(id));
}
return s != nullptr;
@@ -90,7 +90,7 @@
t->lists[id].tail = s->links[id].prev;
}
if (grpc_trace_http2_stream_state.enabled()) {
- gpr_log(GPR_DEBUG, "%p[%d][%s]: remove from %s", t, s->id,
+ gpr_log(GPR_INFO, "%p[%d][%s]: remove from %s", t, s->id,
t->is_client ? "cli" : "svr", stream_list_id_string(id));
}
}
@@ -122,7 +122,7 @@
t->lists[id].tail = s;
s->included[id] = 1;
if (grpc_trace_http2_stream_state.enabled()) {
- gpr_log(GPR_DEBUG, "%p[%d][%s]: add to %s", t, s->id,
+ gpr_log(GPR_INFO, "%p[%d][%s]: add to %s", t, s->id,
t->is_client ? "cli" : "svr", stream_list_id_string(id));
}
}
diff --git a/src/core/ext/transport/chttp2/transport/writing.cc b/src/core/ext/transport/chttp2/transport/writing.cc
index 6f32397..85efe27 100644
--- a/src/core/ext/transport/chttp2/transport/writing.cc
+++ b/src/core/ext/transport/chttp2/transport/writing.cc
@@ -52,7 +52,7 @@
if (!grpc_closure_list_empty(pq->lists[GRPC_CHTTP2_PCL_INFLIGHT])) {
/* ping already in-flight: wait */
if (grpc_http_trace.enabled() || grpc_bdp_estimator_trace.enabled()) {
- gpr_log(GPR_DEBUG, "%s: Ping delayed [%p]: already pinging",
+ gpr_log(GPR_INFO, "%s: Ping delayed [%p]: already pinging",
t->is_client ? "CLIENT" : "SERVER", t->peer_string);
}
return;
@@ -61,7 +61,7 @@
t->ping_policy.max_pings_without_data != 0) {
/* need to receive something of substance before sending a ping again */
if (grpc_http_trace.enabled() || grpc_bdp_estimator_trace.enabled()) {
- gpr_log(GPR_DEBUG, "%s: Ping delayed [%p]: too many recent pings: %d/%d",
+ gpr_log(GPR_INFO, "%s: Ping delayed [%p]: too many recent pings: %d/%d",
t->is_client ? "CLIENT" : "SERVER", t->peer_string,
t->ping_state.pings_before_data_required,
t->ping_policy.max_pings_without_data);
@@ -81,7 +81,7 @@
if (next_allowed_ping > now) {
/* not enough elapsed time between successive pings */
if (grpc_http_trace.enabled() || grpc_bdp_estimator_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"%s: Ping delayed [%p]: not enough time elapsed since last ping. "
" Last ping %f: Next ping %f: Now %f",
t->is_client ? "CLIENT" : "SERVER", t->peer_string,
@@ -107,7 +107,7 @@
GRPC_STATS_INC_HTTP2_PINGS_SENT();
t->ping_state.last_ping_sent_time = now;
if (grpc_http_trace.enabled() || grpc_bdp_estimator_trace.enabled()) {
- gpr_log(GPR_DEBUG, "%s: Ping sent [%p]: %d/%d",
+ gpr_log(GPR_INFO, "%s: Ping sent [%p]: %d/%d",
t->is_client ? "CLIENT" : "SERVER", t->peer_string,
t->ping_state.pings_before_data_required,
t->ping_policy.max_pings_without_data);
@@ -401,7 +401,7 @@
StreamWriteContext(WriteContext* write_context, grpc_chttp2_stream* s)
: write_context_(write_context), t_(write_context->transport()), s_(s) {
GRPC_CHTTP2_IF_TRACING(
- gpr_log(GPR_DEBUG, "W:%p %s[%d] im-(sent,send)=(%d,%d) announce=%d", t_,
+ gpr_log(GPR_INFO, "W:%p %s[%d] im-(sent,send)=(%d,%d) announce=%d", t_,
t_->is_client ? "CLIENT" : "SERVER", s->id,
s->sent_initial_metadata, s->send_initial_metadata != nullptr,
(int)(s->flow_control->local_window_delta() -
diff --git a/src/core/ext/transport/inproc/inproc_transport.cc b/src/core/ext/transport/inproc/inproc_transport.cc
index 67a3800..2c3bff5 100644
--- a/src/core/ext/transport/inproc/inproc_transport.cc
+++ b/src/core/ext/transport/inproc/inproc_transport.cc
@@ -125,12 +125,12 @@
static void op_state_machine(void* arg, grpc_error* error);
static void ref_transport(inproc_transport* t) {
- INPROC_LOG(GPR_DEBUG, "ref_transport %p", t);
+ INPROC_LOG(GPR_INFO, "ref_transport %p", t);
gpr_ref(&t->refs);
}
static void really_destroy_transport(inproc_transport* t) {
- INPROC_LOG(GPR_DEBUG, "really_destroy_transport %p", t);
+ INPROC_LOG(GPR_INFO, "really_destroy_transport %p", t);
grpc_connectivity_state_destroy(&t->connectivity);
if (gpr_unref(&t->mu->refs)) {
gpr_free(t->mu);
@@ -139,7 +139,7 @@
}
static void unref_transport(inproc_transport* t) {
- INPROC_LOG(GPR_DEBUG, "unref_transport %p", t);
+ INPROC_LOG(GPR_INFO, "unref_transport %p", t);
if (gpr_unref(&t->refs)) {
really_destroy_transport(t);
}
@@ -154,17 +154,17 @@
#endif
static void ref_stream(inproc_stream* s, const char* reason) {
- INPROC_LOG(GPR_DEBUG, "ref_stream %p %s", s, reason);
+ INPROC_LOG(GPR_INFO, "ref_stream %p %s", s, reason);
STREAM_REF(s->refs, reason);
}
static void unref_stream(inproc_stream* s, const char* reason) {
- INPROC_LOG(GPR_DEBUG, "unref_stream %p %s", s, reason);
+ INPROC_LOG(GPR_INFO, "unref_stream %p %s", s, reason);
STREAM_UNREF(s->refs, reason);
}
static void really_destroy_stream(inproc_stream* s) {
- INPROC_LOG(GPR_DEBUG, "really_destroy_stream %p", s);
+ INPROC_LOG(GPR_INFO, "really_destroy_stream %p", s);
GRPC_ERROR_UNREF(s->write_buffer_cancel_error);
GRPC_ERROR_UNREF(s->cancel_self_error);
@@ -225,7 +225,7 @@
static int init_stream(grpc_transport* gt, grpc_stream* gs,
grpc_stream_refcount* refcount, const void* server_data,
gpr_arena* arena) {
- INPROC_LOG(GPR_DEBUG, "init_stream %p %p %p", gt, gs, server_data);
+ INPROC_LOG(GPR_INFO, "init_stream %p %p %p", gt, gs, server_data);
inproc_transport* t = reinterpret_cast<inproc_transport*>(gt);
inproc_stream* s = reinterpret_cast<inproc_stream*>(gs);
s->arena = arena;
@@ -282,8 +282,8 @@
// Pass the client-side stream address to the server-side for a ref
ref_stream(s, "inproc_init_stream:clt"); // ref it now on behalf of server
// side to avoid destruction
- INPROC_LOG(GPR_DEBUG, "calling accept stream cb %p %p",
- st->accept_stream_cb, st->accept_stream_data);
+ INPROC_LOG(GPR_INFO, "calling accept stream cb %p %p", st->accept_stream_cb,
+ st->accept_stream_data);
(*st->accept_stream_cb)(st->accept_stream_data, &st->base, (void*)s);
} else {
// This is the server-side and is being called through accept_stream_cb
@@ -378,7 +378,7 @@
int is_rtm = static_cast<int>(op == s->recv_trailing_md_op);
if ((is_sm + is_stm + is_rim + is_rm + is_rtm) == 1) {
- INPROC_LOG(GPR_DEBUG, "%s %p %p %p", msg, s, op, error);
+ INPROC_LOG(GPR_INFO, "%s %p %p %p", msg, s, op, error);
GRPC_CLOSURE_SCHED(op->on_complete, GRPC_ERROR_REF(error));
}
}
@@ -393,7 +393,7 @@
}
static void fail_helper_locked(inproc_stream* s, grpc_error* error) {
- INPROC_LOG(GPR_DEBUG, "op_state_machine %p fail_helper", s);
+ INPROC_LOG(GPR_INFO, "op_state_machine %p fail_helper", s);
// If we're failing this side, we need to make sure that
// we also send or have already sent trailing metadata
if (!s->trailing_md_sent) {
@@ -458,7 +458,7 @@
*s->recv_initial_md_op->payload->recv_initial_metadata
.trailing_metadata_available = true;
}
- INPROC_LOG(GPR_DEBUG,
+ INPROC_LOG(GPR_INFO,
"fail_helper %p scheduling initial-metadata-ready %p %p", s,
error, err);
GRPC_CLOSURE_SCHED(s->recv_initial_md_op->payload->recv_initial_metadata
@@ -472,7 +472,7 @@
s->recv_initial_md_op = nullptr;
}
if (s->recv_message_op) {
- INPROC_LOG(GPR_DEBUG, "fail_helper %p scheduling message-ready %p", s,
+ INPROC_LOG(GPR_INFO, "fail_helper %p scheduling message-ready %p", s,
error);
GRPC_CLOSURE_SCHED(
s->recv_message_op->payload->recv_message.recv_message_ready,
@@ -496,9 +496,8 @@
s->send_trailing_md_op = nullptr;
}
if (s->recv_trailing_md_op) {
- INPROC_LOG(GPR_DEBUG,
- "fail_helper %p scheduling trailing-md-on-complete %p", s,
- error);
+ INPROC_LOG(GPR_INFO, "fail_helper %p scheduling trailing-md-on-complete %p",
+ s, error);
complete_if_batch_end_locked(
s, error, s->recv_trailing_md_op,
"fail_helper scheduling recv-trailing-metadata-on-complete");
@@ -549,7 +548,7 @@
receiver->recv_stream.Init(&receiver->recv_message, 0);
receiver->recv_message_op->payload->recv_message.recv_message->reset(
receiver->recv_stream.get());
- INPROC_LOG(GPR_DEBUG, "message_transfer_locked %p scheduling message-ready",
+ INPROC_LOG(GPR_INFO, "message_transfer_locked %p scheduling message-ready",
receiver);
GRPC_CLOSURE_SCHED(
receiver->recv_message_op->payload->recv_message.recv_message_ready,
@@ -577,7 +576,7 @@
bool needs_close = false;
- INPROC_LOG(GPR_DEBUG, "op_state_machine %p", arg);
+ INPROC_LOG(GPR_INFO, "op_state_machine %p", arg);
inproc_stream* s = static_cast<inproc_stream*>(arg);
gpr_mu* mu = &s->t->mu->mu; // keep aside in case s gets closed
gpr_mu_lock(mu);
@@ -626,7 +625,7 @@
: &other->to_read_trailing_md_filled;
if (*destfilled || s->trailing_md_sent) {
// The buffer is already in use; that's an error!
- INPROC_LOG(GPR_DEBUG, "Extra trailing metadata %p", s);
+ INPROC_LOG(GPR_INFO, "Extra trailing metadata %p", s);
new_err = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Extra trailing metadata");
fail_helper_locked(s, GRPC_ERROR_REF(new_err));
goto done;
@@ -639,7 +638,7 @@
}
s->trailing_md_sent = true;
if (!s->t->is_client && s->trailing_md_recvd && s->recv_trailing_md_op) {
- INPROC_LOG(GPR_DEBUG,
+ INPROC_LOG(GPR_INFO,
"op_state_machine %p scheduling trailing-md-on-complete", s);
GRPC_CLOSURE_SCHED(s->recv_trailing_md_op->on_complete,
GRPC_ERROR_NONE);
@@ -658,7 +657,7 @@
new_err =
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Already recvd initial md");
INPROC_LOG(
- GPR_DEBUG,
+ GPR_INFO,
"op_state_machine %p scheduling on_complete errors for already "
"recvd initial md %p",
s, new_err);
@@ -684,7 +683,7 @@
}
grpc_metadata_batch_clear(&s->to_read_initial_md);
s->to_read_initial_md_filled = false;
- INPROC_LOG(GPR_DEBUG,
+ INPROC_LOG(GPR_INFO,
"op_state_machine %p scheduling initial-metadata-ready %p", s,
new_err);
GRPC_CLOSURE_SCHED(s->recv_initial_md_op->payload->recv_initial_metadata
@@ -696,7 +695,7 @@
s->recv_initial_md_op = nullptr;
if (new_err != GRPC_ERROR_NONE) {
- INPROC_LOG(GPR_DEBUG,
+ INPROC_LOG(GPR_INFO,
"op_state_machine %p scheduling on_complete errors2 %p", s,
new_err);
fail_helper_locked(s, GRPC_ERROR_REF(new_err));
@@ -719,7 +718,7 @@
new_err =
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Already recvd trailing md");
INPROC_LOG(
- GPR_DEBUG,
+ GPR_INFO,
"op_state_machine %p scheduling on_complete errors for already "
"recvd trailing md %p",
s, new_err);
@@ -729,7 +728,7 @@
if (s->recv_message_op != nullptr) {
// This message needs to be wrapped up because it will never be
// satisfied
- INPROC_LOG(GPR_DEBUG, "op_state_machine %p scheduling message-ready", s);
+ INPROC_LOG(GPR_INFO, "op_state_machine %p scheduling message-ready", s);
GRPC_CLOSURE_SCHED(
s->recv_message_op->payload->recv_message.recv_message_ready,
GRPC_ERROR_NONE);
@@ -764,7 +763,7 @@
// (If the server hasn't already sent its trailing md, it doesn't have
// a final status, so don't mark this op complete)
if (s->t->is_client || s->trailing_md_sent) {
- INPROC_LOG(GPR_DEBUG,
+ INPROC_LOG(GPR_INFO,
"op_state_machine %p scheduling trailing-md-on-complete %p",
s, new_err);
GRPC_CLOSURE_SCHED(s->recv_trailing_md_op->on_complete,
@@ -772,21 +771,21 @@
s->recv_trailing_md_op = nullptr;
needs_close = true;
} else {
- INPROC_LOG(GPR_DEBUG,
+ INPROC_LOG(GPR_INFO,
"op_state_machine %p server needs to delay handling "
"trailing-md-on-complete %p",
s, new_err);
}
} else {
INPROC_LOG(
- GPR_DEBUG,
+ GPR_INFO,
"op_state_machine %p has trailing md but not yet waiting for it", s);
}
}
if (s->trailing_md_recvd && s->recv_message_op) {
// No further message will come on this stream, so finish off the
// recv_message_op
- INPROC_LOG(GPR_DEBUG, "op_state_machine %p scheduling message-ready", s);
+ INPROC_LOG(GPR_INFO, "op_state_machine %p scheduling message-ready", s);
GRPC_CLOSURE_SCHED(
s->recv_message_op->payload->recv_message.recv_message_ready,
GRPC_ERROR_NONE);
@@ -810,7 +809,7 @@
// Didn't get the item we wanted so we still need to get
// rescheduled
INPROC_LOG(
- GPR_DEBUG, "op_state_machine %p still needs closure %p %p %p %p %p", s,
+ GPR_INFO, "op_state_machine %p still needs closure %p %p %p %p %p", s,
s->send_message_op, s->send_trailing_md_op, s->recv_initial_md_op,
s->recv_message_op, s->recv_trailing_md_op);
s->ops_needed = true;
@@ -826,8 +825,7 @@
static bool cancel_stream_locked(inproc_stream* s, grpc_error* error) {
bool ret = false; // was the cancel accepted
- INPROC_LOG(GPR_DEBUG, "cancel_stream %p with %s", s,
- grpc_error_string(error));
+ INPROC_LOG(GPR_INFO, "cancel_stream %p with %s", s, grpc_error_string(error));
if (s->cancel_self_error == GRPC_ERROR_NONE) {
ret = true;
s->cancel_self_error = GRPC_ERROR_REF(error);
@@ -877,7 +875,7 @@
static void perform_stream_op(grpc_transport* gt, grpc_stream* gs,
grpc_transport_stream_op_batch* op) {
- INPROC_LOG(GPR_DEBUG, "perform_stream_op %p %p %p", gt, gs, op);
+ INPROC_LOG(GPR_INFO, "perform_stream_op %p %p %p", gt, gs, op);
inproc_stream* s = reinterpret_cast<inproc_stream*>(gs);
gpr_mu* mu = &s->t->mu->mu; // save aside in case s gets closed
gpr_mu_lock(mu);
@@ -907,7 +905,7 @@
// already self-canceled so still give it an error
error = GRPC_ERROR_REF(s->cancel_self_error);
} else {
- INPROC_LOG(GPR_DEBUG, "perform_stream_op %p %s%s%s%s%s%s%s", s,
+ INPROC_LOG(GPR_INFO, "perform_stream_op %p %s%s%s%s%s%s%s", s,
s->t->is_client ? "client" : "server",
op->send_initial_metadata ? " send_initial_metadata" : "",
op->send_message ? " send_message" : "",
@@ -936,7 +934,7 @@
: &other->to_read_initial_md_filled;
if (*destfilled || s->initial_md_sent) {
// The buffer is already in use; that's an error!
- INPROC_LOG(GPR_DEBUG, "Extra initial metadata %p", s);
+ INPROC_LOG(GPR_INFO, "Extra initial metadata %p", s);
error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Extra initial metadata");
} else {
if (!other || !other->closed) {
@@ -1013,7 +1011,7 @@
true;
}
INPROC_LOG(
- GPR_DEBUG,
+ GPR_INFO,
"perform_stream_op error %p scheduling initial-metadata-ready %p",
s, error);
GRPC_CLOSURE_SCHED(
@@ -1022,14 +1020,14 @@
}
if (op->recv_message) {
INPROC_LOG(
- GPR_DEBUG,
+ GPR_INFO,
"perform_stream_op error %p scheduling recv message-ready %p", s,
error);
GRPC_CLOSURE_SCHED(op->payload->recv_message.recv_message_ready,
GRPC_ERROR_REF(error));
}
}
- INPROC_LOG(GPR_DEBUG, "perform_stream_op %p scheduling on_complete %p", s,
+ INPROC_LOG(GPR_INFO, "perform_stream_op %p scheduling on_complete %p", s,
error);
GRPC_CLOSURE_SCHED(on_complete, GRPC_ERROR_REF(error));
}
@@ -1042,7 +1040,7 @@
}
static void close_transport_locked(inproc_transport* t) {
- INPROC_LOG(GPR_DEBUG, "close_transport %p %d", t, t->is_closed);
+ INPROC_LOG(GPR_INFO, "close_transport %p %d", t, t->is_closed);
grpc_connectivity_state_set(
&t->connectivity, GRPC_CHANNEL_SHUTDOWN,
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Closing transport."),
@@ -1063,7 +1061,7 @@
static void perform_transport_op(grpc_transport* gt, grpc_transport_op* op) {
inproc_transport* t = reinterpret_cast<inproc_transport*>(gt);
- INPROC_LOG(GPR_DEBUG, "perform_transport_op %p %p", t, op);
+ INPROC_LOG(GPR_INFO, "perform_transport_op %p %p", t, op);
gpr_mu_lock(&t->mu->mu);
if (op->on_connectivity_state_change) {
grpc_connectivity_state_notify_on_state_change(
@@ -1096,7 +1094,7 @@
static void destroy_stream(grpc_transport* gt, grpc_stream* gs,
grpc_closure* then_schedule_closure) {
- INPROC_LOG(GPR_DEBUG, "destroy_stream %p %p", gs, then_schedule_closure);
+ INPROC_LOG(GPR_INFO, "destroy_stream %p %p", gs, then_schedule_closure);
inproc_stream* s = reinterpret_cast<inproc_stream*>(gs);
s->closure_at_destroy = then_schedule_closure;
really_destroy_stream(s);
@@ -1104,7 +1102,7 @@
static void destroy_transport(grpc_transport* gt) {
inproc_transport* t = reinterpret_cast<inproc_transport*>(gt);
- INPROC_LOG(GPR_DEBUG, "destroy_transport %p", t);
+ INPROC_LOG(GPR_INFO, "destroy_transport %p", t);
gpr_mu_lock(&t->mu->mu);
close_transport_locked(t);
gpr_mu_unlock(&t->mu->mu);
@@ -1165,7 +1163,7 @@
const grpc_channel_args* server_args,
grpc_transport** client_transport,
const grpc_channel_args* client_args) {
- INPROC_LOG(GPR_DEBUG, "inproc_transports_create");
+ INPROC_LOG(GPR_INFO, "inproc_transports_create");
inproc_transport* st =
static_cast<inproc_transport*>(gpr_zalloc(sizeof(*st)));
inproc_transport* ct =
diff --git a/src/core/lib/channel/channel_args.cc b/src/core/lib/channel/channel_args.cc
index 66a86c2..e49d532 100644
--- a/src/core/lib/channel/channel_args.cc
+++ b/src/core/lib/channel/channel_args.cc
@@ -411,3 +411,31 @@
arg.value.pointer.vtable = vtable;
return arg;
}
+
+char* grpc_channel_args_string(const grpc_channel_args* args) {
+ if (args == nullptr) return nullptr;
+ gpr_strvec v;
+ gpr_strvec_init(&v);
+ for (size_t i = 0; i < args->num_args; ++i) {
+ const grpc_arg& arg = args->args[i];
+ char* s;
+ switch (arg.type) {
+ case GRPC_ARG_INTEGER:
+ gpr_asprintf(&s, "%s=%d", arg.key, arg.value.integer);
+ break;
+ case GRPC_ARG_STRING:
+ gpr_asprintf(&s, "%s=%s", arg.key, arg.value.string);
+ break;
+ case GRPC_ARG_POINTER:
+ gpr_asprintf(&s, "%s=%p", arg.key, arg.value.pointer.p);
+ break;
+ default:
+ gpr_asprintf(&s, "arg with unknown type");
+ }
+ gpr_strvec_add(&v, s);
+ }
+ char* result =
+ gpr_strjoin_sep(const_cast<const char**>(v.strs), v.count, ", ", nullptr);
+ gpr_strvec_destroy(&v);
+ return result;
+}
diff --git a/src/core/lib/channel/channel_args.h b/src/core/lib/channel/channel_args.h
index c0d6a17..5ff303a 100644
--- a/src/core/lib/channel/channel_args.h
+++ b/src/core/lib/channel/channel_args.h
@@ -124,4 +124,8 @@
grpc_arg grpc_channel_arg_pointer_create(char* name, void* value,
const grpc_arg_pointer_vtable* vtable);
+// Returns a string representing channel args in human-readable form.
+// Callers takes ownership of result.
+char* grpc_channel_args_string(const grpc_channel_args* args);
+
#endif /* GRPC_CORE_LIB_CHANNEL_CHANNEL_ARGS_H */
diff --git a/src/core/lib/channel/handshaker.cc b/src/core/lib/channel/handshaker.cc
index 9b1af8d..2faeb64 100644
--- a/src/core/lib/channel/handshaker.cc
+++ b/src/core/lib/channel/handshaker.cc
@@ -22,11 +22,15 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/handshaker.h"
+#include "src/core/lib/debug/trace.h"
#include "src/core/lib/iomgr/timer.h"
+grpc_core::TraceFlag grpc_handshaker_trace(false, "handshaker");
+
//
// grpc_handshaker
//
@@ -52,6 +56,10 @@
args);
}
+const char* grpc_handshaker_name(grpc_handshaker* handshaker) {
+ return handshaker->vtable->name;
+}
+
//
// grpc_handshake_manager
//
@@ -127,6 +135,12 @@
void grpc_handshake_manager_add(grpc_handshake_manager* mgr,
grpc_handshaker* handshaker) {
+ if (grpc_handshaker_trace.enabled()) {
+ gpr_log(
+ GPR_INFO,
+ "handshake_manager %p: adding handshaker %s [%p] at index %" PRIuPTR,
+ mgr, grpc_handshaker_name(handshaker), handshaker, mgr->count);
+ }
gpr_mu_lock(&mgr->mu);
// To avoid allocating memory for each handshaker we add, we double
// the number of elements every time we need more.
@@ -172,23 +186,56 @@
GRPC_ERROR_UNREF(why);
}
+static char* handshaker_args_string(grpc_handshaker_args* args) {
+ char* args_str = grpc_channel_args_string(args->args);
+ size_t num_args = args->args != nullptr ? args->args->num_args : 0;
+ size_t read_buffer_length =
+ args->read_buffer != nullptr ? args->read_buffer->length : 0;
+ char* str;
+ gpr_asprintf(&str,
+ "{endpoint=%p, args=%p {size=%" PRIuPTR
+ ": %s}, read_buffer=%p (length=%" PRIuPTR "), exit_early=%d}",
+ args->endpoint, args->args, num_args, args_str,
+ args->read_buffer, read_buffer_length, args->exit_early);
+ gpr_free(args_str);
+ return str;
+}
+
// Helper function to call either the next handshaker or the
// on_handshake_done callback.
// Returns true if we've scheduled the on_handshake_done callback.
static bool call_next_handshaker_locked(grpc_handshake_manager* mgr,
grpc_error* error) {
+ if (grpc_handshaker_trace.enabled()) {
+ char* args_str = handshaker_args_string(&mgr->args);
+ gpr_log(GPR_INFO,
+ "handshake_manager %p: error=%s shutdown=%d index=%" PRIuPTR
+ ", args=%s",
+ mgr, grpc_error_string(error), mgr->shutdown, mgr->index, args_str);
+ gpr_free(args_str);
+ }
GPR_ASSERT(mgr->index <= mgr->count);
// If we got an error or we've been shut down or we're exiting early or
// we've finished the last handshaker, invoke the on_handshake_done
// callback. Otherwise, call the next handshaker.
if (error != GRPC_ERROR_NONE || mgr->shutdown || mgr->args.exit_early ||
mgr->index == mgr->count) {
+ if (grpc_handshaker_trace.enabled()) {
+ gpr_log(GPR_INFO, "handshake_manager %p: handshaking complete", mgr);
+ }
// Cancel deadline timer, since we're invoking the on_handshake_done
// callback now.
grpc_timer_cancel(&mgr->deadline_timer);
GRPC_CLOSURE_SCHED(&mgr->on_handshake_done, error);
mgr->shutdown = true;
} else {
+ if (grpc_handshaker_trace.enabled()) {
+ gpr_log(
+ GPR_INFO,
+ "handshake_manager %p: calling handshaker %s [%p] at index %" PRIuPTR,
+ mgr, grpc_handshaker_name(mgr->handshakers[mgr->index]),
+ mgr->handshakers[mgr->index], mgr->index);
+ }
grpc_handshaker_do_handshake(mgr->handshakers[mgr->index], mgr->acceptor,
&mgr->call_next_handshaker, &mgr->args);
}
diff --git a/src/core/lib/channel/handshaker.h b/src/core/lib/channel/handshaker.h
index dfecd81..be7fd12 100644
--- a/src/core/lib/channel/handshaker.h
+++ b/src/core/lib/channel/handshaker.h
@@ -84,6 +84,9 @@
grpc_tcp_server_acceptor* acceptor,
grpc_closure* on_handshake_done,
grpc_handshaker_args* args);
+
+ /// The name of the handshaker, for debugging purposes.
+ const char* name;
} grpc_handshaker_vtable;
/// Base struct. To subclass, make this the first member of the
@@ -102,6 +105,7 @@
grpc_tcp_server_acceptor* acceptor,
grpc_closure* on_handshake_done,
grpc_handshaker_args* args);
+const char* grpc_handshaker_name(grpc_handshaker* handshaker);
///
/// grpc_handshake_manager
diff --git a/src/core/lib/debug/trace.cc b/src/core/lib/debug/trace.cc
index b0e0f2b..01c1e86 100644
--- a/src/core/lib/debug/trace.cc
+++ b/src/core/lib/debug/trace.cc
@@ -55,7 +55,8 @@
found = true;
}
}
- if (!found) {
+ // check for unknowns, but ignore "", to allow to GRPC_TRACE=
+ if (!found && 0 != strcmp(name, "")) {
gpr_log(GPR_ERROR, "Unknown trace var: '%s'", name);
return false; /* early return */
}
diff --git a/src/core/lib/debug/trace.h b/src/core/lib/debug/trace.h
index bfec92c..28157c6 100644
--- a/src/core/lib/debug/trace.h
+++ b/src/core/lib/debug/trace.h
@@ -57,13 +57,22 @@
const char* name() const { return name_; }
+// This following define may be commented out to ensure that the compiler
+// deletes any "if (tracer.enabled()) {...}" codeblocks. This is useful to
+// test the performance impact tracers have on the system.
+//
+// #define COMPILE_OUT_ALL_TRACERS_IN_OPT_BUILD
+#ifdef COMPILE_OUT_ALL_TRACERS_IN_OPT_BUILD
+ bool enabled() { return false; }
+#else
bool enabled() {
#ifdef GRPC_THREADSAFE_TRACER
return gpr_atm_no_barrier_load(&value_) != 0;
#else
return value_;
-#endif
+#endif // GRPC_THREADSAFE_TRACER
}
+#endif // COMPILE_OUT_ALL_TRACERS_IN_OPT_BUILD
private:
friend void grpc_core::testing::grpc_tracer_enable_flag(TraceFlag* flag);
diff --git a/src/core/lib/gpr/log.cc b/src/core/lib/gpr/log.cc
index 72787ab..01ef112 100644
--- a/src/core/lib/gpr/log.cc
+++ b/src/core/lib/gpr/log.cc
@@ -44,10 +44,16 @@
GPR_UNREACHABLE_CODE(return "UNKNOWN");
}
+int gpr_should_log(gpr_log_severity severity) {
+ return static_cast<gpr_atm>(severity) >=
+ gpr_atm_no_barrier_load(&g_min_severity_to_print)
+ ? 1
+ : 0;
+}
+
void gpr_log_message(const char* file, int line, gpr_log_severity severity,
const char* message) {
- if (static_cast<gpr_atm>(severity) <
- gpr_atm_no_barrier_load(&g_min_severity_to_print)) {
+ if (gpr_should_log(severity) == 0) {
return;
}
diff --git a/src/core/lib/gpr/log_android.cc b/src/core/lib/gpr/log_android.cc
index 0d3ac0f..40ef4c6 100644
--- a/src/core/lib/gpr/log_android.cc
+++ b/src/core/lib/gpr/log_android.cc
@@ -41,6 +41,10 @@
void gpr_log(const char* file, int line, gpr_log_severity severity,
const char* format, ...) {
+ /* Avoid message construction if gpr_log_message won't log */
+ if (gpr_should_log(severity) == 0) {
+ return;
+ }
char* message = NULL;
va_list args;
va_start(args, format);
diff --git a/src/core/lib/gpr/log_linux.cc b/src/core/lib/gpr/log_linux.cc
index e4417d9..561276f 100644
--- a/src/core/lib/gpr/log_linux.cc
+++ b/src/core/lib/gpr/log_linux.cc
@@ -44,6 +44,10 @@
void gpr_log(const char* file, int line, gpr_log_severity severity,
const char* format, ...) {
+ /* Avoid message construction if gpr_log_message won't log */
+ if (gpr_should_log(severity) == 0) {
+ return;
+ }
char* message = nullptr;
va_list args;
va_start(args, format);
diff --git a/src/core/lib/gpr/log_posix.cc b/src/core/lib/gpr/log_posix.cc
index 6f93cde..0acb225 100644
--- a/src/core/lib/gpr/log_posix.cc
+++ b/src/core/lib/gpr/log_posix.cc
@@ -34,6 +34,10 @@
void gpr_log(const char* file, int line, gpr_log_severity severity,
const char* format, ...) {
+ /* Avoid message construction if gpr_log_message won't log */
+ if (gpr_should_log(severity) == 0) {
+ return;
+ }
char buf[64];
char* allocated = nullptr;
char* message = nullptr;
diff --git a/src/core/lib/gpr/log_windows.cc b/src/core/lib/gpr/log_windows.cc
index caaa973..060be57 100644
--- a/src/core/lib/gpr/log_windows.cc
+++ b/src/core/lib/gpr/log_windows.cc
@@ -34,6 +34,11 @@
void gpr_log(const char* file, int line, gpr_log_severity severity,
const char* format, ...) {
+ /* Avoid message construction if gpr_log_message won't log */
+ if (gpr_should_log(severity) == 0) {
+ return;
+ }
+
char* message = NULL;
va_list args;
int ret;
diff --git a/src/core/lib/gprpp/inlined_vector.h b/src/core/lib/gprpp/inlined_vector.h
index ca95aec..f36f6cb 100644
--- a/src/core/lib/gprpp/inlined_vector.h
+++ b/src/core/lib/gprpp/inlined_vector.h
@@ -54,43 +54,43 @@
InlinedVector(const InlinedVector&) = delete;
InlinedVector& operator=(const InlinedVector&) = delete;
+ T* data() {
+ return dynamic_ != nullptr ? dynamic_ : reinterpret_cast<T*>(inline_);
+ }
+
+ const T* data() const {
+ return dynamic_ != nullptr ? dynamic_ : reinterpret_cast<const T*>(inline_);
+ }
+
T& operator[](size_t offset) {
assert(offset < size_);
- if (offset < N) {
- return *reinterpret_cast<T*>(inline_ + offset);
- } else {
- return dynamic_[offset - N];
- }
+ return data()[offset];
}
const T& operator[](size_t offset) const {
assert(offset < size_);
- if (offset < N) {
- return *reinterpret_cast<const T*>(inline_ + offset);
- } else {
- return dynamic_[offset - N];
+ return data()[offset];
+ }
+
+ void reserve(size_t capacity) {
+ if (capacity > capacity_) {
+ T* new_dynamic = static_cast<T*>(gpr_malloc(sizeof(T) * capacity));
+ for (size_t i = 0; i < size_; ++i) {
+ new (&new_dynamic[i]) T(std::move(data()[i]));
+ data()[i].~T();
+ }
+ gpr_free(dynamic_);
+ dynamic_ = new_dynamic;
+ capacity_ = capacity;
}
}
template <typename... Args>
void emplace_back(Args&&... args) {
- if (size_ < N) {
- new (&inline_[size_]) T(std::forward<Args>(args)...);
- } else {
- if (size_ - N == dynamic_capacity_) {
- size_t new_capacity =
- dynamic_capacity_ == 0 ? 2 : dynamic_capacity_ * 2;
- T* new_dynamic = static_cast<T*>(gpr_malloc(sizeof(T) * new_capacity));
- for (size_t i = 0; i < dynamic_capacity_; ++i) {
- new (&new_dynamic[i]) T(std::move(dynamic_[i]));
- dynamic_[i].~T();
- }
- gpr_free(dynamic_);
- dynamic_ = new_dynamic;
- dynamic_capacity_ = new_capacity;
- }
- new (&dynamic_[size_ - N]) T(std::forward<Args>(args)...);
+ if (size_ == capacity_) {
+ reserve(capacity_ * 2);
}
+ new (&(data()[size_])) T(std::forward<Args>(args)...);
++size_;
}
@@ -99,6 +99,7 @@
void push_back(T&& value) { emplace_back(std::move(value)); }
size_t size() const { return size_; }
+ size_t capacity() const { return capacity_; }
void clear() {
destroy_elements();
@@ -109,26 +110,21 @@
void init_data() {
dynamic_ = nullptr;
size_ = 0;
- dynamic_capacity_ = 0;
+ capacity_ = N;
}
void destroy_elements() {
- for (size_t i = 0; i < size_ && i < N; ++i) {
- T& value = *reinterpret_cast<T*>(inline_ + i);
+ for (size_t i = 0; i < size_; ++i) {
+ T& value = data()[i];
value.~T();
}
- if (size_ > N) { // Avoid subtracting two signed values.
- for (size_t i = 0; i < size_ - N; ++i) {
- dynamic_[i].~T();
- }
- }
gpr_free(dynamic_);
}
typename std::aligned_storage<sizeof(T)>::type inline_[N];
T* dynamic_;
size_t size_;
- size_t dynamic_capacity_;
+ size_t capacity_;
};
} // namespace grpc_core
diff --git a/src/core/lib/gprpp/orphanable.h b/src/core/lib/gprpp/orphanable.h
index a5bc8d8..73a7399 100644
--- a/src/core/lib/gprpp/orphanable.h
+++ b/src/core/lib/gprpp/orphanable.h
@@ -100,7 +100,7 @@
void Unref() {
if (gpr_unref(&refs_)) {
- Delete(this);
+ Delete(static_cast<Child*>(this));
}
}
@@ -159,7 +159,7 @@
const char* reason) GRPC_MUST_USE_RESULT {
if (location.Log() && trace_flag_ != nullptr && trace_flag_->enabled()) {
gpr_atm old_refs = gpr_atm_no_barrier_load(&refs_.count);
- gpr_log(GPR_DEBUG, "%s:%p %s:%d ref %" PRIdPTR " -> %" PRIdPTR " %s",
+ gpr_log(GPR_INFO, "%s:%p %s:%d ref %" PRIdPTR " -> %" PRIdPTR " %s",
trace_flag_->name(), this, location.file(), location.line(),
old_refs, old_refs + 1, reason);
}
@@ -173,14 +173,14 @@
void Unref() {
if (gpr_unref(&refs_)) {
- Delete(this);
+ Delete(static_cast<Child*>(this));
}
}
void Unref(const DebugLocation& location, const char* reason) {
if (location.Log() && trace_flag_ != nullptr && trace_flag_->enabled()) {
gpr_atm old_refs = gpr_atm_no_barrier_load(&refs_.count);
- gpr_log(GPR_DEBUG, "%s:%p %s:%d unref %" PRIdPTR " -> %" PRIdPTR " %s",
+ gpr_log(GPR_INFO, "%s:%p %s:%d unref %" PRIdPTR " -> %" PRIdPTR " %s",
trace_flag_->name(), this, location.file(), location.line(),
old_refs, old_refs - 1, reason);
}
diff --git a/src/core/lib/gprpp/ref_counted.h b/src/core/lib/gprpp/ref_counted.h
index 46bfaf7..c67e3f3 100644
--- a/src/core/lib/gprpp/ref_counted.h
+++ b/src/core/lib/gprpp/ref_counted.h
@@ -54,7 +54,7 @@
// friend of this class.
void Unref() {
if (gpr_unref(&refs_)) {
- Delete(this);
+ Delete(static_cast<Child*>(this));
}
}
@@ -100,7 +100,7 @@
const char* reason) GRPC_MUST_USE_RESULT {
if (location.Log() && trace_flag_ != nullptr && trace_flag_->enabled()) {
gpr_atm old_refs = gpr_atm_no_barrier_load(&refs_.count);
- gpr_log(GPR_DEBUG, "%s:%p %s:%d ref %" PRIdPTR " -> %" PRIdPTR " %s",
+ gpr_log(GPR_INFO, "%s:%p %s:%d ref %" PRIdPTR " -> %" PRIdPTR " %s",
trace_flag_->name(), this, location.file(), location.line(),
old_refs, old_refs + 1, reason);
}
@@ -114,14 +114,14 @@
void Unref() {
if (gpr_unref(&refs_)) {
- Delete(this);
+ Delete(static_cast<Child*>(this));
}
}
void Unref(const DebugLocation& location, const char* reason) {
if (location.Log() && trace_flag_ != nullptr && trace_flag_->enabled()) {
gpr_atm old_refs = gpr_atm_no_barrier_load(&refs_.count);
- gpr_log(GPR_DEBUG, "%s:%p %s:%d unref %" PRIdPTR " -> %" PRIdPTR " %s",
+ gpr_log(GPR_INFO, "%s:%p %s:%d unref %" PRIdPTR " -> %" PRIdPTR " %s",
trace_flag_->name(), this, location.file(), location.line(),
old_refs, old_refs - 1, reason);
}
diff --git a/src/core/lib/http/httpcli_security_connector.cc b/src/core/lib/http/httpcli_security_connector.cc
index 0b53d63..50078c3 100644
--- a/src/core/lib/http/httpcli_security_connector.cc
+++ b/src/core/lib/http/httpcli_security_connector.cc
@@ -32,7 +32,6 @@
#include "src/core/lib/security/transport/security_handshaker.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/tsi/ssl_transport_security.h"
-#include "src/core/tsi/transport_security_adapter.h"
typedef struct {
grpc_channel_security_connector base;
@@ -65,8 +64,7 @@
}
}
grpc_handshake_manager_add(
- handshake_mgr, grpc_security_handshaker_create(
- tsi_create_adapter_handshaker(handshaker), &sc->base));
+ handshake_mgr, grpc_security_handshaker_create(handshaker, &sc->base));
}
static void httpcli_ssl_check_peer(grpc_security_connector* sc, tsi_peer peer,
diff --git a/src/core/lib/iomgr/call_combiner.cc b/src/core/lib/iomgr/call_combiner.cc
index 24e11b6..00a839b 100644
--- a/src/core/lib/iomgr/call_combiner.cc
+++ b/src/core/lib/iomgr/call_combiner.cc
@@ -64,7 +64,7 @@
const char* reason) {
GPR_TIMER_SCOPE("call_combiner_start", 0);
if (grpc_call_combiner_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"==> grpc_call_combiner_start() [%p] closure=%p [" DEBUG_FMT_STR
"%s] error=%s",
call_combiner, closure DEBUG_FMT_ARGS, reason,
@@ -73,7 +73,7 @@
size_t prev_size = static_cast<size_t>(
gpr_atm_full_fetch_add(&call_combiner->size, (gpr_atm)1));
if (grpc_call_combiner_trace.enabled()) {
- gpr_log(GPR_DEBUG, " size: %" PRIdPTR " -> %" PRIdPTR, prev_size,
+ gpr_log(GPR_INFO, " size: %" PRIdPTR " -> %" PRIdPTR, prev_size,
prev_size + 1);
}
GRPC_STATS_INC_CALL_COMBINER_LOCKS_SCHEDULED_ITEMS();
@@ -82,7 +82,7 @@
GPR_TIMER_MARK("call_combiner_initiate", 0);
if (grpc_call_combiner_trace.enabled()) {
- gpr_log(GPR_DEBUG, " EXECUTING IMMEDIATELY");
+ gpr_log(GPR_INFO, " EXECUTING IMMEDIATELY");
}
// Queue was empty, so execute this closure immediately.
GRPC_CLOSURE_SCHED(closure, error);
@@ -101,21 +101,21 @@
const char* reason) {
GPR_TIMER_SCOPE("call_combiner_stop", 0);
if (grpc_call_combiner_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"==> grpc_call_combiner_stop() [%p] [" DEBUG_FMT_STR "%s]",
call_combiner DEBUG_FMT_ARGS, reason);
}
size_t prev_size = static_cast<size_t>(
gpr_atm_full_fetch_add(&call_combiner->size, (gpr_atm)-1));
if (grpc_call_combiner_trace.enabled()) {
- gpr_log(GPR_DEBUG, " size: %" PRIdPTR " -> %" PRIdPTR, prev_size,
+ gpr_log(GPR_INFO, " size: %" PRIdPTR " -> %" PRIdPTR, prev_size,
prev_size - 1);
}
GPR_ASSERT(prev_size >= 1);
if (prev_size > 1) {
while (true) {
if (grpc_call_combiner_trace.enabled()) {
- gpr_log(GPR_DEBUG, " checking queue");
+ gpr_log(GPR_INFO, " checking queue");
}
bool empty;
grpc_closure* closure = reinterpret_cast<grpc_closure*>(
@@ -124,19 +124,19 @@
// This can happen either due to a race condition within the mpscq
// code or because of a race with grpc_call_combiner_start().
if (grpc_call_combiner_trace.enabled()) {
- gpr_log(GPR_DEBUG, " queue returned no result; checking again");
+ gpr_log(GPR_INFO, " queue returned no result; checking again");
}
continue;
}
if (grpc_call_combiner_trace.enabled()) {
- gpr_log(GPR_DEBUG, " EXECUTING FROM QUEUE: closure=%p error=%s",
+ gpr_log(GPR_INFO, " EXECUTING FROM QUEUE: closure=%p error=%s",
closure, grpc_error_string(closure->error_data.error));
}
GRPC_CLOSURE_SCHED(closure, closure->error_data.error);
break;
}
} else if (grpc_call_combiner_trace.enabled()) {
- gpr_log(GPR_DEBUG, " queue empty");
+ gpr_log(GPR_INFO, " queue empty");
}
}
@@ -151,7 +151,7 @@
// Otherwise, store the new closure.
if (original_error != GRPC_ERROR_NONE) {
if (grpc_call_combiner_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"call_combiner=%p: scheduling notify_on_cancel callback=%p "
"for pre-existing cancellation",
call_combiner, closure);
@@ -162,7 +162,7 @@
if (gpr_atm_full_cas(&call_combiner->cancel_state, original_state,
(gpr_atm)closure)) {
if (grpc_call_combiner_trace.enabled()) {
- gpr_log(GPR_DEBUG, "call_combiner=%p: setting notify_on_cancel=%p",
+ gpr_log(GPR_INFO, "call_combiner=%p: setting notify_on_cancel=%p",
call_combiner, closure);
}
// If we replaced an earlier closure, invoke the original
@@ -171,7 +171,7 @@
if (original_state != 0) {
closure = (grpc_closure*)original_state;
if (grpc_call_combiner_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"call_combiner=%p: scheduling old cancel callback=%p",
call_combiner, closure);
}
@@ -199,7 +199,7 @@
if (original_state != 0) {
grpc_closure* notify_on_cancel = (grpc_closure*)original_state;
if (grpc_call_combiner_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"call_combiner=%p: scheduling notify_on_cancel callback=%p",
call_combiner, notify_on_cancel);
}
diff --git a/src/core/lib/iomgr/closure.h b/src/core/lib/iomgr/closure.h
index 64527d6..34a4944 100644
--- a/src/core/lib/iomgr/closure.h
+++ b/src/core/lib/iomgr/closure.h
@@ -253,8 +253,8 @@
c->file_initiated = file;
c->line_initiated = line;
c->run = true;
+ GPR_ASSERT(c->cb != nullptr);
#endif
- assert(c->cb);
c->scheduler->vtable->run(c, error);
} else {
GRPC_ERROR_UNREF(error);
@@ -292,8 +292,8 @@
c->file_initiated = file;
c->line_initiated = line;
c->run = false;
+ GPR_ASSERT(c->cb != nullptr);
#endif
- assert(c->cb);
c->scheduler->vtable->sched(c, error);
} else {
GRPC_ERROR_UNREF(error);
@@ -330,8 +330,8 @@
c->file_initiated = file;
c->line_initiated = line;
c->run = false;
+ GPR_ASSERT(c->cb != nullptr);
#endif
- assert(c->cb);
c->scheduler->vtable->sched(c, c->error_data.error);
c = next;
}
diff --git a/src/core/lib/iomgr/combiner.cc b/src/core/lib/iomgr/combiner.cc
index e66df03..9429842 100644
--- a/src/core/lib/iomgr/combiner.cc
+++ b/src/core/lib/iomgr/combiner.cc
@@ -83,12 +83,12 @@
grpc_closure_list_init(&lock->final_list);
GRPC_CLOSURE_INIT(&lock->offload, offload, lock,
grpc_executor_scheduler(GRPC_EXECUTOR_SHORT));
- GRPC_COMBINER_TRACE(gpr_log(GPR_DEBUG, "C:%p create", lock));
+ GRPC_COMBINER_TRACE(gpr_log(GPR_INFO, "C:%p create", lock));
return lock;
}
static void really_destroy(grpc_combiner* lock) {
- GRPC_COMBINER_TRACE(gpr_log(GPR_DEBUG, "C:%p really_destroy", lock));
+ GRPC_COMBINER_TRACE(gpr_log(GPR_INFO, "C:%p really_destroy", lock));
GPR_ASSERT(gpr_atm_no_barrier_load(&lock->state) == 0);
gpr_mpscq_destroy(&lock->queue);
gpr_free(lock);
@@ -97,7 +97,7 @@
static void start_destroy(grpc_combiner* lock) {
gpr_atm old_state = gpr_atm_full_fetch_add(&lock->state, -STATE_UNORPHANED);
GRPC_COMBINER_TRACE(gpr_log(
- GPR_DEBUG, "C:%p really_destroy old_state=%" PRIdPTR, lock, old_state));
+ GPR_INFO, "C:%p really_destroy old_state=%" PRIdPTR, lock, old_state));
if (old_state == 1) {
really_destroy(lock);
}
@@ -159,7 +159,7 @@
GRPC_STATS_INC_COMBINER_LOCKS_SCHEDULED_ITEMS();
grpc_combiner* lock = COMBINER_FROM_CLOSURE_SCHEDULER(cl, scheduler);
gpr_atm last = gpr_atm_full_fetch_add(&lock->state, STATE_ELEM_COUNT_LOW_BIT);
- GRPC_COMBINER_TRACE(gpr_log(GPR_DEBUG,
+ GRPC_COMBINER_TRACE(gpr_log(GPR_INFO,
"C:%p grpc_combiner_execute c=%p last=%" PRIdPTR,
lock, cl, last));
if (last == 1) {
@@ -203,7 +203,7 @@
static void queue_offload(grpc_combiner* lock) {
GRPC_STATS_INC_COMBINER_LOCKS_OFFLOADED();
move_next();
- GRPC_COMBINER_TRACE(gpr_log(GPR_DEBUG, "C:%p queue_offload", lock));
+ GRPC_COMBINER_TRACE(gpr_log(GPR_INFO, "C:%p queue_offload", lock));
GRPC_CLOSURE_SCHED(&lock->offload, GRPC_ERROR_NONE);
}
@@ -218,7 +218,7 @@
bool contended =
gpr_atm_no_barrier_load(&lock->initiating_exec_ctx_or_null) == 0;
- GRPC_COMBINER_TRACE(gpr_log(GPR_DEBUG,
+ GRPC_COMBINER_TRACE(gpr_log(GPR_INFO,
"C:%p grpc_combiner_continue_exec_ctx "
"contended=%d "
"exec_ctx_ready_to_finish=%d "
@@ -242,7 +242,7 @@
(gpr_atm_acq_load(&lock->state) >> 1) > 1) {
gpr_mpscq_node* n = gpr_mpscq_pop(&lock->queue);
GRPC_COMBINER_TRACE(
- gpr_log(GPR_DEBUG, "C:%p maybe_finish_one n=%p", lock, n));
+ gpr_log(GPR_INFO, "C:%p maybe_finish_one n=%p", lock, n));
if (n == nullptr) {
// queue is in an inconsistent state: use this as a cue that we should
// go off and do something else for a while (and come back later)
@@ -266,7 +266,7 @@
while (c != nullptr) {
GPR_TIMER_SCOPE("combiner.exec_1final", 0);
GRPC_COMBINER_TRACE(
- gpr_log(GPR_DEBUG, "C:%p execute_final[%d] c=%p", lock, loops, c));
+ gpr_log(GPR_INFO, "C:%p execute_final[%d] c=%p", lock, loops, c));
grpc_closure* next = c->next_data.next;
grpc_error* error = c->error_data.error;
#ifndef NDEBUG
@@ -284,7 +284,7 @@
gpr_atm old_state =
gpr_atm_full_fetch_add(&lock->state, -STATE_ELEM_COUNT_LOW_BIT);
GRPC_COMBINER_TRACE(
- gpr_log(GPR_DEBUG, "C:%p finish old_state=%" PRIdPTR, lock, old_state));
+ gpr_log(GPR_INFO, "C:%p finish old_state=%" PRIdPTR, lock, old_state));
// Define a macro to ease readability of the following switch statement.
#define OLD_STATE_WAS(orphaned, elem_count) \
(((orphaned) ? 0 : STATE_UNORPHANED) | \
@@ -327,8 +327,8 @@
grpc_combiner* lock =
COMBINER_FROM_CLOSURE_SCHEDULER(closure, finally_scheduler);
GRPC_COMBINER_TRACE(gpr_log(
- GPR_DEBUG, "C:%p grpc_combiner_execute_finally c=%p; ac=%p", lock,
- closure, grpc_core::ExecCtx::Get()->combiner_data()->active_combiner));
+ GPR_INFO, "C:%p grpc_combiner_execute_finally c=%p; ac=%p", lock, closure,
+ grpc_core::ExecCtx::Get()->combiner_data()->active_combiner));
if (grpc_core::ExecCtx::Get()->combiner_data()->active_combiner != lock) {
GPR_TIMER_MARK("slowpath", 0);
GRPC_CLOSURE_SCHED(GRPC_CLOSURE_CREATE(enqueue_finally, closure,
diff --git a/src/core/lib/iomgr/ev_epoll1_linux.cc b/src/core/lib/iomgr/ev_epoll1_linux.cc
index 3ebaf18..e5db1be 100644
--- a/src/core/lib/iomgr/ev_epoll1_linux.cc
+++ b/src/core/lib/iomgr/ev_epoll1_linux.cc
@@ -658,7 +658,7 @@
GRPC_STATS_INC_POLL_EVENTS_RETURNED(r);
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG, "ps: %p poll got %d events", ps, r);
+ gpr_log(GPR_INFO, "ps: %p poll got %d events", ps, r);
}
gpr_atm_rel_store(&g_epoll_set.num_events, r);
@@ -678,7 +678,7 @@
pollset->begin_refs++;
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG, "PS:%p BEGIN_STARTS:%p", pollset, worker);
+ gpr_log(GPR_INFO, "PS:%p BEGIN_STARTS:%p", pollset, worker);
}
if (pollset->seen_inactive) {
@@ -697,7 +697,7 @@
gpr_mu_lock(&neighborhood->mu);
gpr_mu_lock(&pollset->mu);
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG, "PS:%p BEGIN_REORG:%p kick_state=%s is_reassigning=%d",
+ gpr_log(GPR_INFO, "PS:%p BEGIN_REORG:%p kick_state=%s is_reassigning=%d",
pollset, worker, kick_state_string(worker->state),
is_reassigning);
}
@@ -749,7 +749,7 @@
gpr_cv_init(&worker->cv);
while (worker->state == UNKICKED && !pollset->shutting_down) {
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG, "PS:%p BEGIN_WAIT:%p kick_state=%s shutdown=%d",
+ gpr_log(GPR_INFO, "PS:%p BEGIN_WAIT:%p kick_state=%s shutdown=%d",
pollset, worker, kick_state_string(worker->state),
pollset->shutting_down);
}
@@ -766,7 +766,7 @@
}
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"PS:%p BEGIN_DONE:%p kick_state=%s shutdown=%d "
"kicked_without_poller: %d",
pollset, worker, kick_state_string(worker->state),
@@ -809,7 +809,7 @@
if (gpr_atm_no_barrier_cas(&g_active_poller, 0,
(gpr_atm)inspect_worker)) {
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG, " .. choose next poller to be %p",
+ gpr_log(GPR_INFO, " .. choose next poller to be %p",
inspect_worker);
}
SET_KICK_STATE(inspect_worker, DESIGNATED_POLLER);
@@ -820,7 +820,7 @@
}
} else {
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG, " .. beaten to choose next poller");
+ gpr_log(GPR_INFO, " .. beaten to choose next poller");
}
}
// even if we didn't win the cas, there's a worker, we can stop
@@ -838,7 +838,7 @@
}
if (!found_worker) {
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG, " .. mark pollset %p inactive", inspect);
+ gpr_log(GPR_INFO, " .. mark pollset %p inactive", inspect);
}
inspect->seen_inactive = true;
if (inspect == neighborhood->active_root) {
@@ -858,7 +858,7 @@
grpc_pollset_worker** worker_hdl) {
GPR_TIMER_SCOPE("end_worker", 0);
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG, "PS:%p END_WORKER:%p", pollset, worker);
+ gpr_log(GPR_INFO, "PS:%p END_WORKER:%p", pollset, worker);
}
if (worker_hdl != nullptr) *worker_hdl = nullptr;
/* Make sure we appear kicked */
@@ -868,7 +868,7 @@
if (gpr_atm_no_barrier_load(&g_active_poller) == (gpr_atm)worker) {
if (worker->next != worker && worker->next->state == UNKICKED) {
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG, " .. choose next poller to be peer %p", worker);
+ gpr_log(GPR_INFO, " .. choose next poller to be peer %p", worker);
}
GPR_ASSERT(worker->next->initialized_cv);
gpr_atm_no_barrier_store(&g_active_poller, (gpr_atm)worker->next);
@@ -920,7 +920,7 @@
gpr_cv_destroy(&worker->cv);
}
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG, " .. remove worker");
+ gpr_log(GPR_INFO, " .. remove worker");
}
if (EMPTIED == worker_remove(pollset, worker)) {
pollset_maybe_finish_shutdown(pollset);
@@ -1022,7 +1022,7 @@
GRPC_STATS_INC_POLLSET_KICKED_WITHOUT_POLLER();
pollset->kicked_without_poller = true;
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG, " .. kicked_without_poller");
+ gpr_log(GPR_INFO, " .. kicked_without_poller");
}
goto done;
}
@@ -1030,14 +1030,14 @@
if (root_worker->state == KICKED) {
GRPC_STATS_INC_POLLSET_KICKED_AGAIN();
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG, " .. already kicked %p", root_worker);
+ gpr_log(GPR_INFO, " .. already kicked %p", root_worker);
}
SET_KICK_STATE(root_worker, KICKED);
goto done;
} else if (next_worker->state == KICKED) {
GRPC_STATS_INC_POLLSET_KICKED_AGAIN();
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG, " .. already kicked %p", next_worker);
+ gpr_log(GPR_INFO, " .. already kicked %p", next_worker);
}
SET_KICK_STATE(next_worker, KICKED);
goto done;
@@ -1048,7 +1048,7 @@
&g_active_poller)) {
GRPC_STATS_INC_POLLSET_KICK_WAKEUP_FD();
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG, " .. kicked %p", root_worker);
+ gpr_log(GPR_INFO, " .. kicked %p", root_worker);
}
SET_KICK_STATE(root_worker, KICKED);
ret_err = grpc_wakeup_fd_wakeup(&global_wakeup_fd);
@@ -1056,7 +1056,7 @@
} else if (next_worker->state == UNKICKED) {
GRPC_STATS_INC_POLLSET_KICK_WAKEUP_CV();
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG, " .. kicked %p", next_worker);
+ gpr_log(GPR_INFO, " .. kicked %p", next_worker);
}
GPR_ASSERT(next_worker->initialized_cv);
SET_KICK_STATE(next_worker, KICKED);
@@ -1066,7 +1066,7 @@
if (root_worker->state != DESIGNATED_POLLER) {
if (grpc_polling_trace.enabled()) {
gpr_log(
- GPR_DEBUG,
+ GPR_INFO,
" .. kicked root non-poller %p (initialized_cv=%d) (poller=%p)",
root_worker, root_worker->initialized_cv, next_worker);
}
@@ -1079,7 +1079,7 @@
} else {
GRPC_STATS_INC_POLLSET_KICK_WAKEUP_FD();
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG, " .. non-root poller %p (root=%p)", next_worker,
+ gpr_log(GPR_INFO, " .. non-root poller %p (root=%p)", next_worker,
root_worker);
}
SET_KICK_STATE(next_worker, KICKED);
@@ -1095,7 +1095,7 @@
} else {
GRPC_STATS_INC_POLLSET_KICK_OWN_THREAD();
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG, " .. kicked while waking up");
+ gpr_log(GPR_INFO, " .. kicked while waking up");
}
goto done;
}
@@ -1105,14 +1105,14 @@
if (specific_worker->state == KICKED) {
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG, " .. specific worker already kicked");
+ gpr_log(GPR_INFO, " .. specific worker already kicked");
}
goto done;
} else if (gpr_tls_get(&g_current_thread_worker) ==
(intptr_t)specific_worker) {
GRPC_STATS_INC_POLLSET_KICK_OWN_THREAD();
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG, " .. mark %p kicked", specific_worker);
+ gpr_log(GPR_INFO, " .. mark %p kicked", specific_worker);
}
SET_KICK_STATE(specific_worker, KICKED);
goto done;
@@ -1120,7 +1120,7 @@
(grpc_pollset_worker*)gpr_atm_no_barrier_load(&g_active_poller)) {
GRPC_STATS_INC_POLLSET_KICK_WAKEUP_FD();
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG, " .. kick active poller");
+ gpr_log(GPR_INFO, " .. kick active poller");
}
SET_KICK_STATE(specific_worker, KICKED);
ret_err = grpc_wakeup_fd_wakeup(&global_wakeup_fd);
@@ -1128,7 +1128,7 @@
} else if (specific_worker->initialized_cv) {
GRPC_STATS_INC_POLLSET_KICK_WAKEUP_CV();
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG, " .. kick waiting worker");
+ gpr_log(GPR_INFO, " .. kick waiting worker");
}
SET_KICK_STATE(specific_worker, KICKED);
gpr_cv_signal(&specific_worker->cv);
@@ -1136,7 +1136,7 @@
} else {
GRPC_STATS_INC_POLLSET_KICKED_AGAIN();
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG, " .. kick non-waiting worker");
+ gpr_log(GPR_INFO, " .. kick non-waiting worker");
}
SET_KICK_STATE(specific_worker, KICKED);
goto done;
diff --git a/src/core/lib/iomgr/ev_epollex_linux.cc b/src/core/lib/iomgr/ev_epollex_linux.cc
index 0ef7c03..65f1c91 100644
--- a/src/core/lib/iomgr/ev_epollex_linux.cc
+++ b/src/core/lib/iomgr/ev_epollex_linux.cc
@@ -59,7 +59,10 @@
//#define GRPC_EPOLLEX_CREATE_WORKERS_ON_HEAP 1
#define MAX_EPOLL_EVENTS 100
-#define MAX_EPOLL_EVENTS_HANDLED_EACH_POLL_CALL 1
+// TODO(juanlishen): We use a greater-than-one value here as a workaround fix to
+// a keepalive ping timeout issue. We may want to revert https://github
+// .com/grpc/grpc/pull/14943 once we figure out the root cause.
+#define MAX_EPOLL_EVENTS_HANDLED_EACH_POLL_CALL 16
grpc_core::DebugOnlyTraceFlag grpc_trace_pollable_refcount(false,
"pollable_refcount");
@@ -198,6 +201,7 @@
struct grpc_pollset {
gpr_mu mu;
+ gpr_atm worker_count;
pollable* active_pollable;
bool kicked_without_poller;
grpc_closure* shutdown_closure;
@@ -514,7 +518,7 @@
const int epfd = p->epfd;
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG, "add fd %p (%d) to pollable %p", fd, fd->fd, p);
+ gpr_log(GPR_INFO, "add fd %p (%d) to pollable %p", fd, fd->fd, p);
}
struct epoll_event ev_fd;
@@ -556,7 +560,7 @@
/* pollset->mu must be held while calling this function */
static void pollset_maybe_finish_shutdown(grpc_pollset* pollset) {
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"PS:%p (pollable:%p) maybe_finish_shutdown sc=%p (target:!NULL) "
"rw=%p (target:NULL) cpsc=%d (target:0)",
pollset, pollset->active_pollable, pollset->shutdown_closure,
@@ -581,14 +585,14 @@
GPR_ASSERT(specific_worker != nullptr);
if (specific_worker->kicked) {
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG, "PS:%p kicked_specific_but_already_kicked", p);
+ gpr_log(GPR_INFO, "PS:%p kicked_specific_but_already_kicked", p);
}
GRPC_STATS_INC_POLLSET_KICKED_AGAIN();
return GRPC_ERROR_NONE;
}
if (gpr_tls_get(&g_current_thread_worker) == (intptr_t)specific_worker) {
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG, "PS:%p kicked_specific_but_awake", p);
+ gpr_log(GPR_INFO, "PS:%p kicked_specific_but_awake", p);
}
GRPC_STATS_INC_POLLSET_KICK_OWN_THREAD();
specific_worker->kicked = true;
@@ -597,7 +601,7 @@
if (specific_worker == p->root_worker) {
GRPC_STATS_INC_POLLSET_KICK_WAKEUP_FD();
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG, "PS:%p kicked_specific_via_wakeup_fd", p);
+ gpr_log(GPR_INFO, "PS:%p kicked_specific_via_wakeup_fd", p);
}
specific_worker->kicked = true;
grpc_error* error = grpc_wakeup_fd_wakeup(&p->wakeup);
@@ -606,7 +610,7 @@
if (specific_worker->initialized_cv) {
GRPC_STATS_INC_POLLSET_KICK_WAKEUP_CV();
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG, "PS:%p kicked_specific_via_cv", p);
+ gpr_log(GPR_INFO, "PS:%p kicked_specific_via_cv", p);
}
specific_worker->kicked = true;
gpr_cv_signal(&specific_worker->cv);
@@ -622,7 +626,7 @@
GPR_TIMER_SCOPE("pollset_kick", 0);
GRPC_STATS_INC_POLLSET_KICK();
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"PS:%p kick %p tls_pollset=%p tls_worker=%p pollset.root_worker=%p",
pollset, specific_worker,
(void*)gpr_tls_get(&g_current_thread_pollset),
@@ -632,7 +636,7 @@
if (gpr_tls_get(&g_current_thread_pollset) != (intptr_t)pollset) {
if (pollset->root_worker == nullptr) {
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG, "PS:%p kicked_any_without_poller", pollset);
+ gpr_log(GPR_INFO, "PS:%p kicked_any_without_poller", pollset);
}
GRPC_STATS_INC_POLLSET_KICKED_WITHOUT_POLLER();
pollset->kicked_without_poller = true;
@@ -658,7 +662,7 @@
}
} else {
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG, "PS:%p kicked_any_but_awake", pollset);
+ gpr_log(GPR_INFO, "PS:%p kicked_any_but_awake", pollset);
}
GRPC_STATS_INC_POLLSET_KICK_OWN_THREAD();
return GRPC_ERROR_NONE;
@@ -685,6 +689,7 @@
static void pollset_init(grpc_pollset* pollset, gpr_mu** mu) {
gpr_mu_init(&pollset->mu);
+ gpr_atm_no_barrier_store(&pollset->worker_count, 0);
pollset->active_pollable = POLLABLE_REF(g_empty_pollable, "pollset");
pollset->kicked_without_poller = false;
pollset->shutdown_closure = nullptr;
@@ -758,8 +763,20 @@
pollable* pollable_obj, bool drain) {
GPR_TIMER_SCOPE("pollable_process_events", 0);
static const char* err_desc = "pollset_process_events";
+ // Use a simple heuristic to determine how many fd events to process
+ // per loop iteration. (events/workers)
+ int handle_count = 1;
+ int worker_count = gpr_atm_no_barrier_load(&pollset->worker_count);
+ GPR_ASSERT(worker_count > 0);
+ handle_count =
+ (pollable_obj->event_count - pollable_obj->event_cursor) / worker_count;
+ if (handle_count == 0) {
+ handle_count = 1;
+ } else if (handle_count > MAX_EPOLL_EVENTS_HANDLED_EACH_POLL_CALL) {
+ handle_count = MAX_EPOLL_EVENTS_HANDLED_EACH_POLL_CALL;
+ }
grpc_error* error = GRPC_ERROR_NONE;
- for (int i = 0; (drain || i < MAX_EPOLL_EVENTS_HANDLED_EACH_POLL_CALL) &&
+ for (int i = 0; (drain || i < handle_count) &&
pollable_obj->event_cursor != pollable_obj->event_count;
i++) {
int n = pollable_obj->event_cursor++;
@@ -767,7 +784,7 @@
void* data_ptr = ev->data.ptr;
if (1 & (intptr_t)data_ptr) {
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG, "PS:%p got pollset_wakeup %p", pollset, data_ptr);
+ gpr_log(GPR_INFO, "PS:%p got pollset_wakeup %p", pollset, data_ptr);
}
append_error(&error,
grpc_wakeup_fd_consume_wakeup(
@@ -780,7 +797,7 @@
bool read_ev = (ev->events & (EPOLLIN | EPOLLPRI)) != 0;
bool write_ev = (ev->events & EPOLLOUT) != 0;
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"PS:%p got fd %p: cancel=%d read=%d "
"write=%d",
pollset, fd, cancel, read_ev, write_ev);
@@ -810,7 +827,7 @@
if (grpc_polling_trace.enabled()) {
char* desc = pollable_desc(p);
- gpr_log(GPR_DEBUG, "POLLABLE:%p[%s] poll for %dms", p, desc, timeout);
+ gpr_log(GPR_INFO, "POLLABLE:%p[%s] poll for %dms", p, desc, timeout);
gpr_free(desc);
}
@@ -829,7 +846,7 @@
if (r < 0) return GRPC_OS_ERROR(errno, "epoll_wait");
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG, "POLLABLE:%p got %d events", p, r);
+ gpr_log(GPR_INFO, "POLLABLE:%p got %d events", p, r);
}
p->event_cursor = 0;
@@ -884,6 +901,7 @@
GPR_TIMER_SCOPE("begin_worker", 0);
bool do_poll =
(pollset->shutdown_closure == nullptr && !pollset->already_shutdown);
+ gpr_atm_no_barrier_fetch_add(&pollset->worker_count, 1);
if (worker_hdl != nullptr) *worker_hdl = worker;
worker->initialized_cv = false;
worker->kicked = false;
@@ -899,7 +917,7 @@
gpr_mu_unlock(&pollset->mu);
if (grpc_polling_trace.enabled() &&
worker->pollable_obj->root_worker != worker) {
- gpr_log(GPR_DEBUG, "PS:%p wait %p w=%p for %dms", pollset,
+ gpr_log(GPR_INFO, "PS:%p wait %p w=%p for %dms", pollset,
worker->pollable_obj, worker,
poll_deadline_to_millis_timeout(deadline));
}
@@ -907,19 +925,19 @@
if (gpr_cv_wait(&worker->cv, &worker->pollable_obj->mu,
grpc_millis_to_timespec(deadline, GPR_CLOCK_REALTIME))) {
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG, "PS:%p timeout_wait %p w=%p", pollset,
+ gpr_log(GPR_INFO, "PS:%p timeout_wait %p w=%p", pollset,
worker->pollable_obj, worker);
}
do_poll = false;
} else if (worker->kicked) {
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG, "PS:%p wakeup %p w=%p", pollset,
+ gpr_log(GPR_INFO, "PS:%p wakeup %p w=%p", pollset,
worker->pollable_obj, worker);
}
do_poll = false;
} else if (grpc_polling_trace.enabled() &&
worker->pollable_obj->root_worker != worker) {
- gpr_log(GPR_DEBUG, "PS:%p spurious_wakeup %p w=%p", pollset,
+ gpr_log(GPR_INFO, "PS:%p spurious_wakeup %p w=%p", pollset,
worker->pollable_obj, worker);
}
}
@@ -964,6 +982,7 @@
if (worker->initialized_cv) {
gpr_cv_destroy(&worker->cv);
}
+ gpr_atm_no_barrier_fetch_add(&pollset->worker_count, -1);
}
#ifndef NDEBUG
@@ -990,7 +1009,7 @@
WORKER_PTR->originator = gettid();
#endif
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"PS:%p work hdl=%p worker=%p now=%" PRIdPTR " deadline=%" PRIdPTR
" kwp=%d pollable=%p",
pollset, worker_hdl, WORKER_PTR, grpc_core::ExecCtx::Get()->Now(),
@@ -1031,7 +1050,7 @@
static const char* err_desc = "pollset_transition_pollable_from_empty_to_fd";
grpc_error* error = GRPC_ERROR_NONE;
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"PS:%p add fd %p (%d); transition pollable from empty to fd",
pollset, fd, fd->fd);
}
@@ -1048,7 +1067,7 @@
grpc_error* error = GRPC_ERROR_NONE;
if (grpc_polling_trace.enabled()) {
gpr_log(
- GPR_DEBUG,
+ GPR_INFO,
"PS:%p add fd %p (%d); transition pollable from fd %p to multipoller",
pollset, and_add_fd, and_add_fd ? and_add_fd->fd : -1,
pollset->active_pollable->owner_fd);
@@ -1118,7 +1137,7 @@
/* Any workers currently polling on this pollset must now be woked up so
* that they can pick up the new active_pollable */
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"PS:%p active pollable transition from empty to multi",
pollset);
}
@@ -1205,7 +1224,7 @@
static void pollset_set_add_fd(grpc_pollset_set* pss, grpc_fd* fd) {
GPR_TIMER_SCOPE("pollset_set_add_fd", 0);
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG, "PSS:%p: add fd %p (%d)", pss, fd, fd->fd);
+ gpr_log(GPR_INFO, "PSS:%p: add fd %p (%d)", pss, fd, fd->fd);
}
grpc_error* error = GRPC_ERROR_NONE;
static const char* err_desc = "pollset_set_add_fd";
@@ -1229,7 +1248,7 @@
static void pollset_set_del_fd(grpc_pollset_set* pss, grpc_fd* fd) {
GPR_TIMER_SCOPE("pollset_set_del_fd", 0);
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG, "PSS:%p: del fd %p", pss, fd);
+ gpr_log(GPR_INFO, "PSS:%p: del fd %p", pss, fd);
}
pss = pss_lock_adam(pss);
size_t i;
@@ -1250,7 +1269,7 @@
static void pollset_set_del_pollset(grpc_pollset_set* pss, grpc_pollset* ps) {
GPR_TIMER_SCOPE("pollset_set_del_pollset", 0);
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG, "PSS:%p: del pollset %p", pss, ps);
+ gpr_log(GPR_INFO, "PSS:%p: del pollset %p", pss, ps);
}
pss = pss_lock_adam(pss);
size_t i;
@@ -1302,7 +1321,7 @@
static void pollset_set_add_pollset(grpc_pollset_set* pss, grpc_pollset* ps) {
GPR_TIMER_SCOPE("pollset_set_add_pollset", 0);
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG, "PSS:%p: add pollset %p", pss, ps);
+ gpr_log(GPR_INFO, "PSS:%p: add pollset %p", pss, ps);
}
grpc_error* error = GRPC_ERROR_NONE;
static const char* err_desc = "pollset_set_add_pollset";
@@ -1339,7 +1358,7 @@
grpc_pollset_set* b) {
GPR_TIMER_SCOPE("pollset_set_add_pollset_set", 0);
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG, "PSS: merge (%p, %p)", a, b);
+ gpr_log(GPR_INFO, "PSS: merge (%p, %p)", a, b);
}
grpc_error* error = GRPC_ERROR_NONE;
static const char* err_desc = "pollset_set_add_fd";
@@ -1373,7 +1392,7 @@
GPR_SWAP(grpc_pollset_set*, a, b);
}
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG, "PSS: parent %p to %p", b, a);
+ gpr_log(GPR_INFO, "PSS: parent %p to %p", b, a);
}
gpr_ref(&a->refs);
b->parent = a;
diff --git a/src/core/lib/iomgr/ev_epollsig_linux.cc b/src/core/lib/iomgr/ev_epollsig_linux.cc
index 1e30f66..494bc71 100644
--- a/src/core/lib/iomgr/ev_epollsig_linux.cc
+++ b/src/core/lib/iomgr/ev_epollsig_linux.cc
@@ -292,7 +292,7 @@
const char* file, int line) {
if (grpc_polling_trace.enabled()) {
gpr_atm old_cnt = gpr_atm_acq_load(&pi->ref_count);
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"Add ref pi: %p, old:%" PRIdPTR " -> new:%" PRIdPTR
" (%s) - (%s, %d)",
pi, old_cnt, old_cnt + 1, reason, file, line);
@@ -304,7 +304,7 @@
const char* file, int line) {
if (grpc_polling_trace.enabled()) {
gpr_atm old_cnt = gpr_atm_acq_load(&pi->ref_count);
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"Unref pi: %p, old:%" PRIdPTR " -> new:%" PRIdPTR
" (%s) - (%s, %d)",
pi, old_cnt, (old_cnt - 1), reason, file, line);
diff --git a/src/core/lib/iomgr/ev_poll_posix.cc b/src/core/lib/iomgr/ev_poll_posix.cc
index 2e375b4..504787e 100644
--- a/src/core/lib/iomgr/ev_poll_posix.cc
+++ b/src/core/lib/iomgr/ev_poll_posix.cc
@@ -983,7 +983,7 @@
GRPC_SCHEDULING_END_BLOCKING_REGION;
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG, "%p poll=%d", pollset, r);
+ gpr_log(GPR_INFO, "%p poll=%d", pollset, r);
}
if (r < 0) {
@@ -1007,7 +1007,7 @@
} else {
if (pfds[0].revents & POLLIN_CHECK) {
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG, "%p: got_wakeup", pollset);
+ gpr_log(GPR_INFO, "%p: got_wakeup", pollset);
}
work_combine_error(
&error, grpc_wakeup_fd_consume_wakeup(&worker.wakeup_fd->fd));
@@ -1017,7 +1017,7 @@
fd_end_poll(&watchers[i], 0, 0, nullptr);
} else {
if (grpc_polling_trace.enabled()) {
- gpr_log(GPR_DEBUG, "%p got_event: %d r:%d w:%d [%d]", pollset,
+ gpr_log(GPR_INFO, "%p got_event: %d r:%d w:%d [%d]", pollset,
pfds[i].fd, (pfds[i].revents & POLLIN_CHECK) != 0,
(pfds[i].revents & POLLOUT_CHECK) != 0, pfds[i].revents);
}
@@ -1530,6 +1530,12 @@
// This function overrides poll() to handle condition variable wakeup fds
static int cvfd_poll(struct pollfd* fds, nfds_t nfds, int timeout) {
+ if (timeout == 0) {
+ // Don't bother using background threads for polling if timeout is 0,
+ // poll-cv might not wait for a poll to return otherwise.
+ // https://github.com/grpc/grpc/issues/13298
+ return poll(fds, nfds, 0);
+ }
unsigned int i;
int res, idx;
grpc_cv_node* pollcv;
diff --git a/src/core/lib/iomgr/ev_posix.cc b/src/core/lib/iomgr/ev_posix.cc
index 8b80070..4ea63fc 100644
--- a/src/core/lib/iomgr/ev_posix.cc
+++ b/src/core/lib/iomgr/ev_posix.cc
@@ -46,9 +46,9 @@
#ifndef NDEBUG
// Polling API trace only enabled in debug builds
-#define GRPC_POLLING_API_TRACE(format, ...) \
- if (grpc_polling_api_trace.enabled()) { \
- gpr_log(GPR_DEBUG, "(polling-api) " format, __VA_ARGS__); \
+#define GRPC_POLLING_API_TRACE(format, ...) \
+ if (grpc_polling_api_trace.enabled()) { \
+ gpr_log(GPR_INFO, "(polling-api) " format, __VA_ARGS__); \
}
#else
#define GRPC_POLLING_API_TRACE(...)
diff --git a/src/core/lib/iomgr/executor.cc b/src/core/lib/iomgr/executor.cc
index b017db5..f19f8cf 100644
--- a/src/core/lib/iomgr/executor.cc
+++ b/src/core/lib/iomgr/executor.cc
@@ -69,7 +69,7 @@
gpr_log(GPR_DEBUG, "EXECUTOR: run %p [created by %s:%d]", c,
c->file_created, c->line_created);
#else
- gpr_log(GPR_DEBUG, "EXECUTOR: run %p", c);
+ gpr_log(GPR_INFO, "EXECUTOR: run %p", c);
#endif
}
#ifndef NDEBUG
@@ -150,7 +150,7 @@
size_t subtract_depth = 0;
for (;;) {
if (executor_trace.enabled()) {
- gpr_log(GPR_DEBUG, "EXECUTOR[%d]: step (sub_depth=%" PRIdPTR ")",
+ gpr_log(GPR_INFO, "EXECUTOR[%d]: step (sub_depth=%" PRIdPTR ")",
static_cast<int>(ts - g_thread_state), subtract_depth);
}
gpr_mu_lock(&ts->mu);
@@ -161,7 +161,7 @@
}
if (ts->shutdown) {
if (executor_trace.enabled()) {
- gpr_log(GPR_DEBUG, "EXECUTOR[%d]: shutdown",
+ gpr_log(GPR_INFO, "EXECUTOR[%d]: shutdown",
static_cast<int>(ts - g_thread_state));
}
gpr_mu_unlock(&ts->mu);
@@ -172,7 +172,7 @@
ts->elems = GRPC_CLOSURE_LIST_INIT;
gpr_mu_unlock(&ts->mu);
if (executor_trace.enabled()) {
- gpr_log(GPR_DEBUG, "EXECUTOR[%d]: execute",
+ gpr_log(GPR_INFO, "EXECUTOR[%d]: execute",
static_cast<int>(ts - g_thread_state));
}
@@ -199,7 +199,7 @@
gpr_log(GPR_DEBUG, "EXECUTOR: schedule %p (created %s:%d) inline",
closure, closure->file_created, closure->line_created);
#else
- gpr_log(GPR_DEBUG, "EXECUTOR: schedule %p inline", closure);
+ gpr_log(GPR_INFO, "EXECUTOR: schedule %p inline", closure);
#endif
}
grpc_closure_list_append(grpc_core::ExecCtx::Get()->closure_list(),
@@ -225,7 +225,7 @@
closure, is_short ? "short" : "long", closure->file_created,
closure->line_created, static_cast<int>(ts - g_thread_state));
#else
- gpr_log(GPR_DEBUG, "EXECUTOR: try to schedule %p (%s) to thread %d",
+ gpr_log(GPR_INFO, "EXECUTOR: try to schedule %p (%s) to thread %d",
closure, is_short ? "short" : "long",
(int)(ts - g_thread_state));
#endif
diff --git a/src/core/lib/iomgr/fork_posix.cc b/src/core/lib/iomgr/fork_posix.cc
index f8645ab..6c506eb 100644
--- a/src/core/lib/iomgr/fork_posix.cc
+++ b/src/core/lib/iomgr/fork_posix.cc
@@ -74,7 +74,6 @@
grpc_timer_manager_set_threading(true);
grpc_core::ExecCtx exec_ctx;
grpc_executor_set_threading(true);
- grpc_core::ExecCtx::Get()->Flush();
}
}
diff --git a/src/core/lib/iomgr/gevent_util.h b/src/core/lib/iomgr/gevent_util.h
new file mode 100644
index 0000000..de30543
--- /dev/null
+++ b/src/core/lib/iomgr/gevent_util.h
@@ -0,0 +1,46 @@
+/*
+ *
+ * Copyright 2018 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_IOMGR_GEVENT_UTIL_H
+#define GRPC_CORE_LIB_IOMGR_GEVENT_UTIL_H
+
+#include <grpc/support/port_platform.h>
+
+#include <grpc/impl/codegen/slice.h>
+#include <grpc/status.h>
+#include "src/core/lib/iomgr/error.h"
+
+// These are only used by the gRPC Python extension for gevent
+// support. They are easier to define here (rather than in Cython)
+// because Cython doesn't handle #defines well.
+
+grpc_error* grpc_socket_error(char* error) {
+ return grpc_error_set_int(GRPC_ERROR_CREATE_FROM_COPIED_STRING(error),
+ GRPC_ERROR_INT_GRPC_STATUS,
+ GRPC_STATUS_UNAVAILABLE);
+}
+
+char* grpc_slice_buffer_start(grpc_slice_buffer* buffer, int i) {
+ return (char*)GRPC_SLICE_START_PTR(buffer->slices[i]);
+}
+
+int grpc_slice_buffer_length(grpc_slice_buffer* buffer, int i) {
+ return GRPC_SLICE_LENGTH(buffer->slices[i]);
+}
+
+#endif
diff --git a/src/core/lib/iomgr/iomgr_custom.h b/src/core/lib/iomgr/iomgr_custom.h
index ceb6c65..57cc2f9 100644
--- a/src/core/lib/iomgr/iomgr_custom.h
+++ b/src/core/lib/iomgr/iomgr_custom.h
@@ -37,7 +37,7 @@
GPR_ASSERT(gpr_thd_currentid() == g_init_thread)
#else
#define GRPC_CUSTOM_IOMGR_ASSERT_SAME_THREAD()
-#endif /* GRPC_UV_THREAD_CHECK */
+#endif /* GRPC_CUSTOM_IOMGR_THREAD_CHECK */
void grpc_custom_iomgr_init(grpc_socket_vtable* socket,
grpc_custom_resolver_vtable* resolver,
diff --git a/src/core/lib/iomgr/lockfree_event.h b/src/core/lib/iomgr/lockfree_event.h
index b507b94..d6a6c22 100644
--- a/src/core/lib/iomgr/lockfree_event.h
+++ b/src/core/lib/iomgr/lockfree_event.h
@@ -42,12 +42,23 @@
void InitEvent();
void DestroyEvent();
+ // Returns true if fd has been shutdown, false otherwise.
bool IsShutdown() const {
return (gpr_atm_no_barrier_load(&state_) & kShutdownBit) != 0;
}
+ // Schedules \a closure when the event is received (see SetReady()) or the
+ // shutdown state has been set. Note that the event may have already been
+ // received, in which case the closure would be scheduled immediately.
+ // If the shutdown state has already been set, then \a closure is scheduled
+ // with the shutdown error.
void NotifyOn(grpc_closure* closure);
+
+ // Sets the shutdown state. If a closure had been provided by NotifyOn and has
+ // not yet been scheduled, it will be scheduled with \a error.
bool SetShutdown(grpc_error* error);
+
+ // Signals that the event has been received.
void SetReady();
private:
diff --git a/src/core/lib/iomgr/port.h b/src/core/lib/iomgr/port.h
index c1dcc52..a397012 100644
--- a/src/core/lib/iomgr/port.h
+++ b/src/core/lib/iomgr/port.h
@@ -22,8 +22,10 @@
#define GRPC_CORE_LIB_IOMGR_PORT_H
#ifdef GRPC_UV
+#ifndef GRPC_CUSTOM_SOCKET
#define GRPC_CUSTOM_SOCKET
#endif
+#endif
#if defined(GRPC_CUSTOM_SOCKET)
// Do Nothing
#elif defined(GPR_MANYLINUX1)
diff --git a/src/core/lib/iomgr/resource_quota.cc b/src/core/lib/iomgr/resource_quota.cc
index 8c42dd7..8cf4fe9 100644
--- a/src/core/lib/iomgr/resource_quota.cc
+++ b/src/core/lib/iomgr/resource_quota.cc
@@ -289,7 +289,7 @@
GRPC_RULIST_AWAITING_ALLOCATION))) {
gpr_mu_lock(&resource_user->mu);
if (grpc_resource_quota_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"RQ: check allocation for user %p shutdown=%" PRIdPTR
" free_pool=%" PRId64,
resource_user, gpr_atm_no_barrier_load(&resource_user->shutdown),
@@ -315,7 +315,7 @@
resource_quota->free_pool -= amt;
rq_update_estimate(resource_quota);
if (grpc_resource_quota_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"RQ %s %s: grant alloc %" PRId64
" bytes; rq_free_pool -> %" PRId64,
resource_quota->name, resource_user->name, amt,
@@ -323,7 +323,7 @@
}
} else if (grpc_resource_quota_trace.enabled() &&
resource_user->free_pool >= 0) {
- gpr_log(GPR_DEBUG, "RQ %s %s: discard already satisfied alloc request",
+ gpr_log(GPR_INFO, "RQ %s %s: discard already satisfied alloc request",
resource_quota->name, resource_user->name);
}
if (resource_user->free_pool >= 0) {
@@ -353,7 +353,7 @@
resource_quota->free_pool += amt;
rq_update_estimate(resource_quota);
if (grpc_resource_quota_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"RQ %s %s: reclaim_from_per_user_free_pool %" PRId64
" bytes; rq_free_pool -> %" PRId64,
resource_quota->name, resource_user->name, amt,
@@ -376,9 +376,8 @@
grpc_resource_user* resource_user = rulist_pop_head(resource_quota, list);
if (resource_user == nullptr) return false;
if (grpc_resource_quota_trace.enabled()) {
- gpr_log(GPR_DEBUG, "RQ %s %s: initiate %s reclamation",
- resource_quota->name, resource_user->name,
- destructive ? "destructive" : "benign");
+ gpr_log(GPR_INFO, "RQ %s %s: initiate %s reclamation", resource_quota->name,
+ resource_user->name, destructive ? "destructive" : "benign");
}
resource_quota->reclaiming = true;
grpc_resource_quota_ref_internal(resource_quota);
@@ -506,7 +505,7 @@
static void ru_shutdown(void* ru, grpc_error* error) {
if (grpc_resource_quota_trace.enabled()) {
- gpr_log(GPR_DEBUG, "RU shutdown %p", ru);
+ gpr_log(GPR_INFO, "RU shutdown %p", ru);
}
grpc_resource_user* resource_user = static_cast<grpc_resource_user*>(ru);
gpr_mu_lock(&resource_user->mu);
@@ -793,7 +792,7 @@
resource_user->free_pool -= static_cast<int64_t>(size);
resource_user->outstanding_allocations += static_cast<int64_t>(size);
if (grpc_resource_quota_trace.enabled()) {
- gpr_log(GPR_DEBUG, "RQ %s %s: alloc %" PRIdPTR "; free_pool -> %" PRId64,
+ gpr_log(GPR_INFO, "RQ %s %s: alloc %" PRIdPTR "; free_pool -> %" PRId64,
resource_user->resource_quota->name, resource_user->name, size,
resource_user->free_pool);
}
@@ -816,7 +815,7 @@
bool was_zero_or_negative = resource_user->free_pool <= 0;
resource_user->free_pool += static_cast<int64_t>(size);
if (grpc_resource_quota_trace.enabled()) {
- gpr_log(GPR_DEBUG, "RQ %s %s: free %" PRIdPTR "; free_pool -> %" PRId64,
+ gpr_log(GPR_INFO, "RQ %s %s: free %" PRIdPTR "; free_pool -> %" PRId64,
resource_user->resource_quota->name, resource_user->name, size,
resource_user->free_pool);
}
@@ -842,7 +841,7 @@
void grpc_resource_user_finish_reclamation(grpc_resource_user* resource_user) {
if (grpc_resource_quota_trace.enabled()) {
- gpr_log(GPR_DEBUG, "RQ %s %s: reclamation complete",
+ gpr_log(GPR_INFO, "RQ %s %s: reclamation complete",
resource_user->resource_quota->name, resource_user->name);
}
GRPC_CLOSURE_SCHED(
diff --git a/src/core/lib/iomgr/sockaddr_utils.cc b/src/core/lib/iomgr/sockaddr_utils.cc
index df25f77..1b66dce 100644
--- a/src/core/lib/iomgr/sockaddr_utils.cc
+++ b/src/core/lib/iomgr/sockaddr_utils.cc
@@ -204,6 +204,8 @@
if (grpc_inet_pton(GRPC_AF_INET6, addr, &addr6->sin6_addr) == 1) {
addr6->sin6_family = GRPC_AF_INET6;
+ addr6->sin6_flowinfo = 0;
+ addr6->sin6_scope_id = 0;
out->len = sizeof(grpc_sockaddr_in6);
} else if (grpc_inet_pton(GRPC_AF_INET, addr, &addr4->sin_addr) == 1) {
addr4->sin_family = GRPC_AF_INET;
diff --git a/src/core/lib/iomgr/socket_utils_common_posix.cc b/src/core/lib/iomgr/socket_utils_common_posix.cc
index c52e237..04a1767 100644
--- a/src/core/lib/iomgr/socket_utils_common_posix.cc
+++ b/src/core/lib/iomgr/socket_utils_common_posix.cc
@@ -181,6 +181,30 @@
#endif
}
+static gpr_once g_probe_so_reuesport_once = GPR_ONCE_INIT;
+static int g_support_so_reuseport = false;
+
+void probe_so_reuseport_once(void) {
+#ifndef GPR_MANYLINUX1
+ int s = socket(AF_INET, SOCK_STREAM, 0);
+ if (s < 0) {
+ /* This might be an ipv6-only environment in which case 'socket(AF_INET,..)'
+ call would fail. Try creating IPv6 socket in that case */
+ s = socket(AF_INET6, SOCK_STREAM, 0);
+ }
+ if (s >= 0) {
+ g_support_so_reuseport = GRPC_LOG_IF_ERROR(
+ "check for SO_REUSEPORT", grpc_set_socket_reuse_port(s, 1));
+ close(s);
+ }
+#endif
+}
+
+bool grpc_is_socket_reuse_port_supported() {
+ gpr_once_init(&g_probe_so_reuesport_once, probe_so_reuseport_once);
+ return g_support_so_reuseport;
+}
+
/* disable nagle */
grpc_error* grpc_set_socket_low_latency(int fd, int low_latency) {
int val = (low_latency != 0);
diff --git a/src/core/lib/iomgr/socket_utils_linux.cc b/src/core/lib/iomgr/socket_utils_linux.cc
index f506329..34f93cc 100644
--- a/src/core/lib/iomgr/socket_utils_linux.cc
+++ b/src/core/lib/iomgr/socket_utils_linux.cc
@@ -33,8 +33,6 @@
int grpc_accept4(int sockfd, grpc_resolved_address* resolved_addr, int nonblock,
int cloexec) {
int flags = 0;
- GPR_ASSERT(sizeof(socklen_t) <= sizeof(size_t));
- GPR_ASSERT(resolved_addr->len <= (socklen_t)-1);
flags |= nonblock ? SOCK_NONBLOCK : 0;
flags |= cloexec ? SOCK_CLOEXEC : 0;
return accept4(sockfd, reinterpret_cast<grpc_sockaddr*>(resolved_addr->addr),
diff --git a/src/core/lib/iomgr/socket_utils_posix.cc b/src/core/lib/iomgr/socket_utils_posix.cc
index d5d00af..c48da52 100644
--- a/src/core/lib/iomgr/socket_utils_posix.cc
+++ b/src/core/lib/iomgr/socket_utils_posix.cc
@@ -34,10 +34,8 @@
int grpc_accept4(int sockfd, grpc_resolved_address* resolved_addr, int nonblock,
int cloexec) {
int fd, flags;
- GPR_ASSERT(sizeof(socklen_t) <= sizeof(size_t));
- GPR_ASSERT(resolved_addr->len <= (socklen_t)-1);
- fd = accept(sockfd, (grpc_sockaddr*)resolved_addr->addr,
- (socklen_t*)&resolved_addr->len);
+ fd = accept(sockfd, reinterpret_cast<grpc_sockaddr*>(resolved_addr->addr),
+ &resolved_addr->len);
if (fd >= 0) {
if (nonblock) {
flags = fcntl(fd, F_GETFL, 0);
diff --git a/src/core/lib/iomgr/socket_utils_posix.h b/src/core/lib/iomgr/socket_utils_posix.h
index 1f50e8d..b3fd58a 100644
--- a/src/core/lib/iomgr/socket_utils_posix.h
+++ b/src/core/lib/iomgr/socket_utils_posix.h
@@ -44,6 +44,9 @@
/* set a socket to reuse old addresses */
grpc_error* grpc_set_socket_reuse_addr(int fd, int reuse);
+/* return true if SO_REUSEPORT is supported */
+bool grpc_is_socket_reuse_port_supported();
+
/* disable nagle */
grpc_error* grpc_set_socket_low_latency(int fd, int low_latency);
diff --git a/src/core/lib/iomgr/socket_utils_uv.cc b/src/core/lib/iomgr/socket_utils_uv.cc
index 8538abc..7eba40c 100644
--- a/src/core/lib/iomgr/socket_utils_uv.cc
+++ b/src/core/lib/iomgr/socket_utils_uv.cc
@@ -38,8 +38,8 @@
}
const char* grpc_inet_ntop(int af, const void* src, char* dst, size_t size) {
- /* Windows InetNtopA wants a mutable ip pointer */
- return inet_ntop(af, src, dst, (socklen_t)size);
+ uv_inet_ntop(af, src, dst, size);
+ return dst;
}
#endif /* GRPC_UV */
diff --git a/src/core/lib/iomgr/tcp_client_custom.cc b/src/core/lib/iomgr/tcp_client_custom.cc
index 55632a5..932c79e 100644
--- a/src/core/lib/iomgr/tcp_client_custom.cc
+++ b/src/core/lib/iomgr/tcp_client_custom.cc
@@ -66,7 +66,7 @@
grpc_custom_tcp_connect* connect = socket->connector;
if (grpc_tcp_trace.enabled()) {
const char* str = grpc_error_string(error);
- gpr_log(GPR_DEBUG, "CLIENT_CONNECT: %s: on_alarm: error=%s",
+ gpr_log(GPR_INFO, "CLIENT_CONNECT: %s: on_alarm: error=%s",
connect->addr_name, str);
}
if (error == GRPC_ERROR_NONE) {
@@ -136,7 +136,7 @@
connect->refs = 2;
if (grpc_tcp_trace.enabled()) {
- gpr_log(GPR_DEBUG, "CLIENT_CONNECT: %p %s: asynchronously connecting",
+ gpr_log(GPR_INFO, "CLIENT_CONNECT: %p %s: asynchronously connecting",
socket, connect->addr_name);
}
diff --git a/src/core/lib/iomgr/tcp_client_posix.cc b/src/core/lib/iomgr/tcp_client_posix.cc
index 9f19b83..6144d38 100644
--- a/src/core/lib/iomgr/tcp_client_posix.cc
+++ b/src/core/lib/iomgr/tcp_client_posix.cc
@@ -104,7 +104,7 @@
async_connect* ac = static_cast<async_connect*>(acp);
if (grpc_tcp_trace.enabled()) {
const char* str = grpc_error_string(error);
- gpr_log(GPR_DEBUG, "CLIENT_CONNECT: %s: on_alarm: error=%s", ac->addr_str,
+ gpr_log(GPR_INFO, "CLIENT_CONNECT: %s: on_alarm: error=%s", ac->addr_str,
str);
}
gpr_mu_lock(&ac->mu);
@@ -141,8 +141,8 @@
if (grpc_tcp_trace.enabled()) {
const char* str = grpc_error_string(error);
- gpr_log(GPR_DEBUG, "CLIENT_CONNECT: %s: on_writable: error=%s",
- ac->addr_str, str);
+ gpr_log(GPR_INFO, "CLIENT_CONNECT: %s: on_writable: error=%s", ac->addr_str,
+ str);
}
gpr_mu_lock(&ac->mu);
@@ -325,7 +325,7 @@
ac->channel_args = grpc_channel_args_copy(channel_args);
if (grpc_tcp_trace.enabled()) {
- gpr_log(GPR_DEBUG, "CLIENT_CONNECT: %s: asynchronously connecting fd %p",
+ gpr_log(GPR_INFO, "CLIENT_CONNECT: %s: asynchronously connecting fd %p",
ac->addr_str, fdobj);
}
diff --git a/src/core/lib/iomgr/tcp_custom.cc b/src/core/lib/iomgr/tcp_custom.cc
index 2b1fc93..b3b2934 100644
--- a/src/core/lib/iomgr/tcp_custom.cc
+++ b/src/core/lib/iomgr/tcp_custom.cc
@@ -125,16 +125,16 @@
static void call_read_cb(custom_tcp_endpoint* tcp, grpc_error* error) {
grpc_closure* cb = tcp->read_cb;
if (grpc_tcp_trace.enabled()) {
- gpr_log(GPR_DEBUG, "TCP:%p call_cb %p %p:%p", tcp->socket, cb, cb->cb,
+ gpr_log(GPR_INFO, "TCP:%p call_cb %p %p:%p", tcp->socket, cb, cb->cb,
cb->cb_arg);
size_t i;
const char* str = grpc_error_string(error);
- gpr_log(GPR_DEBUG, "read: error=%s", str);
+ gpr_log(GPR_INFO, "read: error=%s", str);
for (i = 0; i < tcp->read_slices->count; i++) {
char* dump = grpc_dump_slice(tcp->read_slices->slices[i],
GPR_DUMP_HEX | GPR_DUMP_ASCII);
- gpr_log(GPR_DEBUG, "READ %p (peer=%s): %s", tcp, tcp->peer_string, dump);
+ gpr_log(GPR_INFO, "READ %p (peer=%s): %s", tcp, tcp->peer_string, dump);
gpr_free(dump);
}
}
@@ -171,7 +171,7 @@
static void tcp_read_allocation_done(void* tcpp, grpc_error* error) {
custom_tcp_endpoint* tcp = (custom_tcp_endpoint*)tcpp;
if (grpc_tcp_trace.enabled()) {
- gpr_log(GPR_DEBUG, "TCP:%p read_allocation_done: %s", tcp->socket,
+ gpr_log(GPR_INFO, "TCP:%p read_allocation_done: %s", tcp->socket,
grpc_error_string(error));
}
if (error == GRPC_ERROR_NONE) {
@@ -188,7 +188,7 @@
}
if (grpc_tcp_trace.enabled()) {
const char* str = grpc_error_string(error);
- gpr_log(GPR_DEBUG, "Initiating read on %p: error=%s", tcp->socket, str);
+ gpr_log(GPR_INFO, "Initiating read on %p: error=%s", tcp->socket, str);
}
}
@@ -214,7 +214,7 @@
tcp->write_cb = nullptr;
if (grpc_tcp_trace.enabled()) {
const char* str = grpc_error_string(error);
- gpr_log(GPR_DEBUG, "write complete on %p: error=%s", tcp->socket, str);
+ gpr_log(GPR_INFO, "write complete on %p: error=%s", tcp->socket, str);
}
TCP_UNREF(tcp, "write");
GRPC_CLOSURE_SCHED(cb, error);
@@ -231,8 +231,8 @@
for (j = 0; j < write_slices->count; j++) {
char* data = grpc_dump_slice(write_slices->slices[j],
GPR_DUMP_HEX | GPR_DUMP_ASCII);
- gpr_log(GPR_DEBUG, "WRITE %p (peer=%s): %s", tcp->socket,
- tcp->peer_string, data);
+ gpr_log(GPR_INFO, "WRITE %p (peer=%s): %s", tcp->socket, tcp->peer_string,
+ data);
gpr_free(data);
}
}
@@ -283,7 +283,7 @@
if (!tcp->shutting_down) {
if (grpc_tcp_trace.enabled()) {
const char* str = grpc_error_string(why);
- gpr_log(GPR_DEBUG, "TCP %p shutdown why=%s", tcp->socket, str);
+ gpr_log(GPR_INFO, "TCP %p shutdown why=%s", tcp->socket, str);
}
tcp->shutting_down = true;
// GRPC_CLOSURE_SCHED(tcp->read_cb, GRPC_ERROR_REF(why));
@@ -345,7 +345,7 @@
grpc_core::ExecCtx exec_ctx;
if (grpc_tcp_trace.enabled()) {
- gpr_log(GPR_DEBUG, "Creating TCP endpoint %p", socket);
+ gpr_log(GPR_INFO, "Creating TCP endpoint %p", socket);
}
memset(tcp, 0, sizeof(custom_tcp_endpoint));
socket->refs++;
diff --git a/src/core/lib/iomgr/tcp_custom.h b/src/core/lib/iomgr/tcp_custom.h
index 22caa14..784ef84 100644
--- a/src/core/lib/iomgr/tcp_custom.h
+++ b/src/core/lib/iomgr/tcp_custom.h
@@ -62,8 +62,6 @@
const grpc_sockaddr* addr, int* len);
grpc_error* (*getsockname)(grpc_custom_socket* socket,
const grpc_sockaddr* addr, int* len);
- grpc_error* (*setsockopt)(grpc_custom_socket* socket, int level, int optname,
- const void* optval, uint32_t optlen);
grpc_error* (*bind)(grpc_custom_socket* socket, const grpc_sockaddr* addr,
size_t len, int flags);
grpc_error* (*listen)(grpc_custom_socket* socket);
diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc
index 205af22..153be05 100644
--- a/src/core/lib/iomgr/tcp_posix.cc
+++ b/src/core/lib/iomgr/tcp_posix.cc
@@ -120,7 +120,7 @@
static void done_poller(void* bp, grpc_error* error_ignored) {
backup_poller* p = static_cast<backup_poller*>(bp);
if (grpc_tcp_trace.enabled()) {
- gpr_log(GPR_DEBUG, "BACKUP_POLLER:%p destroy", p);
+ gpr_log(GPR_INFO, "BACKUP_POLLER:%p destroy", p);
}
grpc_pollset_destroy(BACKUP_POLLER_POLLSET(p));
gpr_free(p);
@@ -129,7 +129,7 @@
static void run_poller(void* bp, grpc_error* error_ignored) {
backup_poller* p = static_cast<backup_poller*>(bp);
if (grpc_tcp_trace.enabled()) {
- gpr_log(GPR_DEBUG, "BACKUP_POLLER:%p run", p);
+ gpr_log(GPR_INFO, "BACKUP_POLLER:%p run", p);
}
gpr_mu_lock(p->pollset_mu);
grpc_millis deadline = grpc_core::ExecCtx::Get()->Now() + 10 * GPR_MS_PER_SEC;
@@ -145,18 +145,18 @@
gpr_mu_lock(p->pollset_mu);
bool cas_ok = gpr_atm_full_cas(&g_backup_poller, (gpr_atm)p, 0);
if (grpc_tcp_trace.enabled()) {
- gpr_log(GPR_DEBUG, "BACKUP_POLLER:%p done cas_ok=%d", p, cas_ok);
+ gpr_log(GPR_INFO, "BACKUP_POLLER:%p done cas_ok=%d", p, cas_ok);
}
gpr_mu_unlock(p->pollset_mu);
if (grpc_tcp_trace.enabled()) {
- gpr_log(GPR_DEBUG, "BACKUP_POLLER:%p shutdown", p);
+ gpr_log(GPR_INFO, "BACKUP_POLLER:%p shutdown", p);
}
grpc_pollset_shutdown(BACKUP_POLLER_POLLSET(p),
GRPC_CLOSURE_INIT(&p->run_poller, done_poller, p,
grpc_schedule_on_exec_ctx));
} else {
if (grpc_tcp_trace.enabled()) {
- gpr_log(GPR_DEBUG, "BACKUP_POLLER:%p reschedule", p);
+ gpr_log(GPR_INFO, "BACKUP_POLLER:%p reschedule", p);
}
GRPC_CLOSURE_SCHED(&p->run_poller, GRPC_ERROR_NONE);
}
@@ -167,7 +167,7 @@
gpr_atm old_count =
gpr_atm_no_barrier_fetch_add(&g_uncovered_notifications_pending, -1);
if (grpc_tcp_trace.enabled()) {
- gpr_log(GPR_DEBUG, "BACKUP_POLLER:%p uncover cnt %d->%d", p,
+ gpr_log(GPR_INFO, "BACKUP_POLLER:%p uncover cnt %d->%d", p,
static_cast<int>(old_count), static_cast<int>(old_count) - 1);
}
GPR_ASSERT(old_count != 1);
@@ -178,7 +178,7 @@
gpr_atm old_count =
gpr_atm_no_barrier_fetch_add(&g_uncovered_notifications_pending, 2);
if (grpc_tcp_trace.enabled()) {
- gpr_log(GPR_DEBUG, "BACKUP_POLLER: cover cnt %d->%d",
+ gpr_log(GPR_INFO, "BACKUP_POLLER: cover cnt %d->%d",
static_cast<int>(old_count), 2 + static_cast<int>(old_count));
}
if (old_count == 0) {
@@ -186,7 +186,7 @@
p = static_cast<backup_poller*>(
gpr_zalloc(sizeof(*p) + grpc_pollset_size()));
if (grpc_tcp_trace.enabled()) {
- gpr_log(GPR_DEBUG, "BACKUP_POLLER:%p create", p);
+ gpr_log(GPR_INFO, "BACKUP_POLLER:%p create", p);
}
grpc_pollset_init(BACKUP_POLLER_POLLSET(p), &p->pollset_mu);
gpr_atm_rel_store(&g_backup_poller, (gpr_atm)p);
@@ -201,7 +201,7 @@
}
}
if (grpc_tcp_trace.enabled()) {
- gpr_log(GPR_DEBUG, "BACKUP_POLLER:%p add %p", p, tcp);
+ gpr_log(GPR_INFO, "BACKUP_POLLER:%p add %p", p, tcp);
}
grpc_pollset_add_fd(BACKUP_POLLER_POLLSET(p), tcp->em_fd);
if (old_count != 0) {
@@ -211,7 +211,7 @@
static void notify_on_read(grpc_tcp* tcp) {
if (grpc_tcp_trace.enabled()) {
- gpr_log(GPR_DEBUG, "TCP:%p notify_on_read", tcp);
+ gpr_log(GPR_INFO, "TCP:%p notify_on_read", tcp);
}
GRPC_CLOSURE_INIT(&tcp->read_done_closure, tcp_handle_read, tcp,
grpc_schedule_on_exec_ctx);
@@ -220,7 +220,7 @@
static void notify_on_write(grpc_tcp* tcp) {
if (grpc_tcp_trace.enabled()) {
- gpr_log(GPR_DEBUG, "TCP:%p notify_on_write", tcp);
+ gpr_log(GPR_INFO, "TCP:%p notify_on_write", tcp);
}
cover_self(tcp);
GRPC_CLOSURE_INIT(&tcp->write_done_closure,
@@ -231,7 +231,7 @@
static void tcp_drop_uncovered_then_handle_write(void* arg, grpc_error* error) {
if (grpc_tcp_trace.enabled()) {
- gpr_log(GPR_DEBUG, "TCP:%p got_write: %s", arg, grpc_error_string(error));
+ gpr_log(GPR_INFO, "TCP:%p got_write: %s", arg, grpc_error_string(error));
}
drop_uncovered(static_cast<grpc_tcp*>(arg));
tcp_handle_write(arg, error);
@@ -351,15 +351,15 @@
grpc_closure* cb = tcp->read_cb;
if (grpc_tcp_trace.enabled()) {
- gpr_log(GPR_DEBUG, "TCP:%p call_cb %p %p:%p", tcp, cb, cb->cb, cb->cb_arg);
+ gpr_log(GPR_INFO, "TCP:%p call_cb %p %p:%p", tcp, cb, cb->cb, cb->cb_arg);
size_t i;
const char* str = grpc_error_string(error);
- gpr_log(GPR_DEBUG, "read: error=%s", str);
+ gpr_log(GPR_INFO, "read: error=%s", str);
for (i = 0; i < tcp->incoming_buffer->count; i++) {
char* dump = grpc_dump_slice(tcp->incoming_buffer->slices[i],
GPR_DUMP_HEX | GPR_DUMP_ASCII);
- gpr_log(GPR_DEBUG, "READ %p (peer=%s): %s", tcp, tcp->peer_string, dump);
+ gpr_log(GPR_INFO, "READ %p (peer=%s): %s", tcp, tcp->peer_string, dump);
gpr_free(dump);
}
}
@@ -371,7 +371,7 @@
#define MAX_READ_IOVEC 4
static void tcp_do_read(grpc_tcp* tcp) {
- GPR_TIMER_SCOPE("tcp_continue_read", 0);
+ GPR_TIMER_SCOPE("tcp_do_read", 0);
struct msghdr msg;
struct iovec iov[MAX_READ_IOVEC];
ssize_t read_bytes;
@@ -441,7 +441,7 @@
static void tcp_read_allocation_done(void* tcpp, grpc_error* error) {
grpc_tcp* tcp = static_cast<grpc_tcp*>(tcpp);
if (grpc_tcp_trace.enabled()) {
- gpr_log(GPR_DEBUG, "TCP:%p read_allocation_done: %s", tcp,
+ gpr_log(GPR_INFO, "TCP:%p read_allocation_done: %s", tcp,
grpc_error_string(error));
}
if (error != GRPC_ERROR_NONE) {
@@ -459,13 +459,13 @@
if (tcp->incoming_buffer->length < target_read_size &&
tcp->incoming_buffer->count < MAX_READ_IOVEC) {
if (grpc_tcp_trace.enabled()) {
- gpr_log(GPR_DEBUG, "TCP:%p alloc_slices", tcp);
+ gpr_log(GPR_INFO, "TCP:%p alloc_slices", tcp);
}
grpc_resource_user_alloc_slices(&tcp->slice_allocator, target_read_size, 1,
tcp->incoming_buffer);
} else {
if (grpc_tcp_trace.enabled()) {
- gpr_log(GPR_DEBUG, "TCP:%p do_read", tcp);
+ gpr_log(GPR_INFO, "TCP:%p do_read", tcp);
}
tcp_do_read(tcp);
}
@@ -475,7 +475,7 @@
grpc_tcp* tcp = static_cast<grpc_tcp*>(arg);
GPR_ASSERT(!tcp->finished_edge);
if (grpc_tcp_trace.enabled()) {
- gpr_log(GPR_DEBUG, "TCP:%p got_read: %s", tcp, grpc_error_string(error));
+ gpr_log(GPR_INFO, "TCP:%p got_read: %s", tcp, grpc_error_string(error));
}
if (error != GRPC_ERROR_NONE) {
@@ -618,7 +618,7 @@
if (!tcp_flush(tcp, &error)) {
if (grpc_tcp_trace.enabled()) {
- gpr_log(GPR_DEBUG, "write: delayed");
+ gpr_log(GPR_INFO, "write: delayed");
}
notify_on_write(tcp);
} else {
@@ -626,7 +626,7 @@
tcp->write_cb = nullptr;
if (grpc_tcp_trace.enabled()) {
const char* str = grpc_error_string(error);
- gpr_log(GPR_DEBUG, "write: %s", str);
+ gpr_log(GPR_INFO, "write: %s", str);
}
GRPC_CLOSURE_RUN(cb, error);
@@ -646,7 +646,7 @@
for (i = 0; i < buf->count; i++) {
char* data =
grpc_dump_slice(buf->slices[i], GPR_DUMP_HEX | GPR_DUMP_ASCII);
- gpr_log(GPR_DEBUG, "WRITE %p (peer=%s): %s", tcp, tcp->peer_string, data);
+ gpr_log(GPR_INFO, "WRITE %p (peer=%s): %s", tcp, tcp->peer_string, data);
gpr_free(data);
}
}
@@ -668,13 +668,13 @@
TCP_REF(tcp, "write");
tcp->write_cb = cb;
if (grpc_tcp_trace.enabled()) {
- gpr_log(GPR_DEBUG, "write: delayed");
+ gpr_log(GPR_INFO, "write: delayed");
}
notify_on_write(tcp);
} else {
if (grpc_tcp_trace.enabled()) {
const char* str = grpc_error_string(error);
- gpr_log(GPR_DEBUG, "write: %s", str);
+ gpr_log(GPR_INFO, "write: %s", str);
}
GRPC_CLOSURE_SCHED(cb, error);
}
diff --git a/src/core/lib/iomgr/tcp_server_custom.cc b/src/core/lib/iomgr/tcp_server_custom.cc
index be92e61..019b354 100644
--- a/src/core/lib/iomgr/tcp_server_custom.cc
+++ b/src/core/lib/iomgr/tcp_server_custom.cc
@@ -222,10 +222,10 @@
}
if (grpc_tcp_trace.enabled()) {
if (peer_name_string) {
- gpr_log(GPR_DEBUG, "SERVER_CONNECT: %p accepted connection: %s",
+ gpr_log(GPR_INFO, "SERVER_CONNECT: %p accepted connection: %s",
sp->server, peer_name_string);
} else {
- gpr_log(GPR_DEBUG, "SERVER_CONNECT: %p accepted connection", sp->server);
+ gpr_log(GPR_INFO, "SERVER_CONNECT: %p accepted connection", sp->server);
}
}
ep = custom_tcp_endpoint_create(socket, sp->server->resource_quota,
@@ -377,10 +377,10 @@
grpc_sockaddr_to_string(&port_string, addr, 0);
const char* str = grpc_error_string(error);
if (port_string) {
- gpr_log(GPR_DEBUG, "SERVER %p add_port %s error=%s", s, port_string, str);
+ gpr_log(GPR_INFO, "SERVER %p add_port %s error=%s", s, port_string, str);
gpr_free(port_string);
} else {
- gpr_log(GPR_DEBUG, "SERVER %p add_port error=%s", s, str);
+ gpr_log(GPR_INFO, "SERVER %p add_port error=%s", s, str);
}
}
@@ -393,13 +393,6 @@
grpc_custom_socket_vtable->init(socket, family);
if (error == GRPC_ERROR_NONE) {
-#if defined(GPR_LINUX) && defined(SO_REUSEPORT)
- if (family == AF_INET || family == AF_INET6) {
- int enable = 1;
- grpc_custom_socket_vtable->setsockopt(socket, SOL_SOCKET, SO_REUSEPORT,
- &enable, sizeof(enable));
- }
-#endif /* GPR_LINUX && SO_REUSEPORT */
error = add_socket_to_server(s, socket, addr, port_index, &sp);
}
gpr_free(allocated_addr);
@@ -426,7 +419,7 @@
(void)pollset_count;
GRPC_CUSTOM_IOMGR_ASSERT_SAME_THREAD();
if (grpc_tcp_trace.enabled()) {
- gpr_log(GPR_DEBUG, "SERVER_START %p", server);
+ gpr_log(GPR_INFO, "SERVER_START %p", server);
}
GPR_ASSERT(on_accept_cb);
GPR_ASSERT(!server->on_accept_cb);
diff --git a/src/core/lib/iomgr/tcp_server_posix.cc b/src/core/lib/iomgr/tcp_server_posix.cc
index 4e1d90e..153ac63 100644
--- a/src/core/lib/iomgr/tcp_server_posix.cc
+++ b/src/core/lib/iomgr/tcp_server_posix.cc
@@ -55,39 +55,18 @@
#include "src/core/lib/iomgr/tcp_server_utils_posix.h"
#include "src/core/lib/iomgr/unix_sockets_posix.h"
-static gpr_once check_init = GPR_ONCE_INIT;
-static bool has_so_reuseport = false;
-
-static void init(void) {
-#ifndef GPR_MANYLINUX1
- int s = socket(AF_INET, SOCK_STREAM, 0);
- if (s < 0) {
- /* This might be an ipv6-only environment in which case 'socket(AF_INET,..)'
- call would fail. Try creating IPv6 socket in that case */
- s = socket(AF_INET6, SOCK_STREAM, 0);
- }
- if (s >= 0) {
- has_so_reuseport = GRPC_LOG_IF_ERROR("check for SO_REUSEPORT",
- grpc_set_socket_reuse_port(s, 1));
- close(s);
- }
-#endif
-}
-
static grpc_error* tcp_server_create(grpc_closure* shutdown_complete,
const grpc_channel_args* args,
grpc_tcp_server** server) {
- gpr_once_init(&check_init, init);
-
grpc_tcp_server* s =
static_cast<grpc_tcp_server*>(gpr_zalloc(sizeof(grpc_tcp_server)));
- s->so_reuseport = has_so_reuseport;
+ s->so_reuseport = grpc_is_socket_reuse_port_supported();
s->expand_wildcard_addrs = false;
for (size_t i = 0; i < (args == nullptr ? 0 : args->num_args); i++) {
if (0 == strcmp(GRPC_ARG_ALLOW_REUSEPORT, args->args[i].key)) {
if (args->args[i].type == GRPC_ARG_INTEGER) {
- s->so_reuseport =
- has_so_reuseport && (args->args[i].value.integer != 0);
+ s->so_reuseport = grpc_is_socket_reuse_port_supported() &&
+ (args->args[i].value.integer != 0);
} else {
gpr_free(s);
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(GRPC_ARG_ALLOW_REUSEPORT
@@ -249,7 +228,7 @@
gpr_asprintf(&name, "tcp-server-connection:%s", addr_str);
if (grpc_tcp_trace.enabled()) {
- gpr_log(GPR_DEBUG, "SERVER_CONNECT: incoming connection: %s", addr_str);
+ gpr_log(GPR_INFO, "SERVER_CONNECT: incoming connection: %s", addr_str);
}
grpc_fd* fdobj = grpc_fd_create(fd, name);
@@ -367,7 +346,8 @@
err = grpc_create_dualstack_socket(&listener->addr, SOCK_STREAM, 0, &dsmode,
&fd);
if (err != GRPC_ERROR_NONE) return err;
- err = grpc_tcp_server_prepare_socket(fd, &listener->addr, true, &port);
+ err = grpc_tcp_server_prepare_socket(listener->server, fd, &listener->addr,
+ true, &port);
if (err != GRPC_ERROR_NONE) return err;
listener->server->nports++;
grpc_sockaddr_to_string(&addr_str, &listener->addr, 1);
diff --git a/src/core/lib/iomgr/tcp_server_utils_posix.h b/src/core/lib/iomgr/tcp_server_utils_posix.h
index 34d6813..dd19909 100644
--- a/src/core/lib/iomgr/tcp_server_utils_posix.h
+++ b/src/core/lib/iomgr/tcp_server_utils_posix.h
@@ -113,7 +113,7 @@
int* out_port);
/* Prepare a recently-created socket for listening. */
-grpc_error* grpc_tcp_server_prepare_socket(int fd,
+grpc_error* grpc_tcp_server_prepare_socket(grpc_tcp_server*, int fd,
const grpc_resolved_address* addr,
bool so_reuseport, int* port);
/* Ruturn true if the platform supports ifaddrs */
diff --git a/src/core/lib/iomgr/tcp_server_utils_posix_common.cc b/src/core/lib/iomgr/tcp_server_utils_posix_common.cc
index 0734453..2d95aa6 100644
--- a/src/core/lib/iomgr/tcp_server_utils_posix_common.cc
+++ b/src/core/lib/iomgr/tcp_server_utils_posix_common.cc
@@ -87,7 +87,7 @@
char* name;
grpc_error* err =
- grpc_tcp_server_prepare_socket(fd, addr, s->so_reuseport, &port);
+ grpc_tcp_server_prepare_socket(s, fd, addr, s->so_reuseport, &port);
if (err == GRPC_ERROR_NONE) {
GPR_ASSERT(port > 0);
grpc_sockaddr_to_string(&addr_str, addr, 1);
@@ -144,7 +144,7 @@
}
/* Prepare a recently-created socket for listening. */
-grpc_error* grpc_tcp_server_prepare_socket(int fd,
+grpc_error* grpc_tcp_server_prepare_socket(grpc_tcp_server* s, int fd,
const grpc_resolved_address* addr,
bool so_reuseport, int* port) {
grpc_resolved_address sockname_temp;
@@ -170,7 +170,18 @@
err = grpc_set_socket_no_sigpipe_if_possible(fd);
if (err != GRPC_ERROR_NONE) goto error;
- GPR_ASSERT(addr->len < ~(socklen_t)0);
+ if (s->channel_args) {
+ for (size_t i = 0; i < s->channel_args->num_args; i++) {
+ if (0 == strcmp(s->channel_args->args[i].key, GRPC_ARG_SOCKET_MUTATOR)) {
+ GPR_ASSERT(s->channel_args->args[i].type == GRPC_ARG_POINTER);
+ grpc_socket_mutator* mutator = static_cast<grpc_socket_mutator*>(
+ s->channel_args->args[i].value.pointer.p);
+ err = grpc_set_socket_with_mutator(fd, mutator);
+ if (err != GRPC_ERROR_NONE) goto error;
+ }
+ }
+ }
+
if (bind(fd, reinterpret_cast<grpc_sockaddr*>(const_cast<char*>(addr->addr)),
addr->len) < 0) {
err = GRPC_OS_ERROR(errno, "bind");
diff --git a/src/core/lib/iomgr/tcp_server_windows.cc b/src/core/lib/iomgr/tcp_server_windows.cc
index 77f3811..b01afdc 100644
--- a/src/core/lib/iomgr/tcp_server_windows.cc
+++ b/src/core/lib/iomgr/tcp_server_windows.cc
@@ -129,6 +129,7 @@
gpr_free(sp);
}
grpc_channel_args_destroy(s->channel_args);
+ gpr_mu_destroy(&s->mu);
gpr_free(s);
}
diff --git a/src/core/lib/iomgr/tcp_uv.cc b/src/core/lib/iomgr/tcp_uv.cc
index 5e31669..8d0e4a5 100644
--- a/src/core/lib/iomgr/tcp_uv.cc
+++ b/src/core/lib/iomgr/tcp_uv.cc
@@ -192,9 +192,21 @@
if (status != 0) {
return tcp_error_create("Failed to initialize UV tcp handle", status);
}
+#if defined(GPR_LINUX) && defined(SO_REUSEPORT)
+ if (domain == AF_INET || domain == AF_INET6) {
+ int enable = 1;
+ int fd;
+ uv_fileno((uv_handle_t*)tcp, &fd);
+ // TODO Handle error here.
+ setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &enable, sizeof(enable));
+ }
+#endif
uv_socket->write_buffers = nullptr;
uv_socket->read_len = 0;
uv_tcp_nodelay(uv_socket->handle, 1);
+ // Node uses a garbage collector to call destructors, so we don't
+ // want to hold the uv loop open with active gRPC objects.
+ uv_unref((uv_handle_t*)uv_socket->handle);
uv_socket->pending_connection = false;
uv_socket->accept_socket = nullptr;
uv_socket->accept_error = GRPC_ERROR_NONE;
@@ -299,17 +311,6 @@
return tcp_error_create("Failed to listen to port", status);
}
-static grpc_error* uv_socket_setsockopt(grpc_custom_socket* socket, int level,
- int option_name, const void* optval,
- socklen_t option_len) {
- int fd;
- uv_socket_t* uv_socket = (uv_socket_t*)socket->impl;
- uv_fileno((uv_handle_t*)uv_socket->handle, &fd);
- // TODO Handle error here. Also, does this work on windows??
- setsockopt(fd, level, option_name, &optval, (socklen_t)option_len);
- return GRPC_ERROR_NONE;
-}
-
static void uv_tc_on_connect(uv_connect_t* req, int status) {
grpc_custom_socket* socket = (grpc_custom_socket*)req->data;
uv_socket_t* uv_socket = (uv_socket_t*)socket->impl;
@@ -340,7 +341,6 @@
static grpc_resolved_addresses* handle_addrinfo_result(
struct addrinfo* result) {
struct addrinfo* resp;
- struct addrinfo* prev;
size_t i;
grpc_resolved_addresses* addresses =
(grpc_resolved_addresses*)gpr_malloc(sizeof(grpc_resolved_addresses));
@@ -350,16 +350,13 @@
}
addresses->addrs = (grpc_resolved_address*)gpr_malloc(
sizeof(grpc_resolved_address) * addresses->naddrs);
- i = 0;
- resp = result;
- while (resp != nullptr) {
+ for (resp = result, i = 0; resp != nullptr; resp = resp->ai_next, i++) {
memcpy(&addresses->addrs[i].addr, resp->ai_addr, resp->ai_addrlen);
addresses->addrs[i].len = resp->ai_addrlen;
- i++;
- prev = resp;
- resp = resp->ai_next;
- gpr_free(prev);
}
+ // addrinfo objects are allocated by libuv (e.g. in uv_getaddrinfo)
+ // and not by gpr_malloc
+ uv_freeaddrinfo(result);
return addresses;
}
@@ -415,10 +412,9 @@
grpc_custom_resolver_vtable uv_resolver_vtable = {uv_resolve, uv_resolve_async};
grpc_socket_vtable grpc_uv_socket_vtable = {
- uv_socket_init, uv_socket_connect, uv_socket_destroy,
- uv_socket_shutdown, uv_socket_close, uv_socket_write,
- uv_socket_read, uv_socket_getpeername, uv_socket_getsockname,
- uv_socket_setsockopt, uv_socket_bind, uv_socket_listen,
- uv_socket_accept};
+ uv_socket_init, uv_socket_connect, uv_socket_destroy,
+ uv_socket_shutdown, uv_socket_close, uv_socket_write,
+ uv_socket_read, uv_socket_getpeername, uv_socket_getsockname,
+ uv_socket_bind, uv_socket_listen, uv_socket_accept};
#endif
diff --git a/src/core/lib/iomgr/tcp_windows.cc b/src/core/lib/iomgr/tcp_windows.cc
index 04e6f11..5d316d4 100644
--- a/src/core/lib/iomgr/tcp_windows.cc
+++ b/src/core/lib/iomgr/tcp_windows.cc
@@ -74,12 +74,28 @@
: GRPC_WSA_ERROR(WSAGetLastError(), "setsockopt(IPV6_V6ONLY)");
}
+static grpc_error* enable_loopback_fast_path(SOCKET sock) {
+ int status;
+ uint32_t param = 1;
+ DWORD ret;
+ status = WSAIoctl(sock, /*SIO_LOOPBACK_FAST_PATH==*/_WSAIOW(IOC_VENDOR, 16),
+ ¶m, sizeof(param), NULL, 0, &ret, 0, 0);
+ if (status == SOCKET_ERROR) {
+ status = WSAGetLastError();
+ }
+ return status == 0 || status == WSAEOPNOTSUPP
+ ? GRPC_ERROR_NONE
+ : GRPC_WSA_ERROR(status, "WSAIoctl(SIO_LOOPBACK_FAST_PATH)");
+}
+
grpc_error* grpc_tcp_prepare_socket(SOCKET sock) {
grpc_error* err;
err = set_non_block(sock);
if (err != GRPC_ERROR_NONE) return err;
err = set_dualstack(sock);
if (err != GRPC_ERROR_NONE) return err;
+ err = enable_loopback_fast_path(sock);
+ if (err != GRPC_ERROR_NONE) return err;
return GRPC_ERROR_NONE;
}
diff --git a/src/core/lib/iomgr/timer_generic.cc b/src/core/lib/iomgr/timer_generic.cc
index 93e654b..de2256f 100644
--- a/src/core/lib/iomgr/timer_generic.cc
+++ b/src/core/lib/iomgr/timer_generic.cc
@@ -97,6 +97,12 @@
}
}
+static void destroy_timer_ht() {
+ for (int i = 0; i < NUM_HASH_BUCKETS; i++) {
+ gpr_mu_destroy(&g_hash_mu[i]);
+ }
+}
+
static bool is_in_ht(grpc_timer* t) {
size_t i = GPR_HASH_POINTER(t, NUM_HASH_BUCKETS);
@@ -188,6 +194,7 @@
}
#define INIT_TIMER_HASH_TABLE() init_timer_ht()
+#define DESTROY_TIMER_HASH_TABLE() destroy_timer_ht()
#define ADD_TO_HASH_TABLE(t) add_to_ht((t))
#define REMOVE_FROM_HASH_TABLE(t) remove_from_ht((t))
#define VALIDATE_NON_PENDING_TIMER(t) validate_non_pending_timer((t))
@@ -195,6 +202,7 @@
#else
#define INIT_TIMER_HASH_TABLE()
+#define DESTROY_TIMER_HASH_TABLE()
#define ADD_TO_HASH_TABLE(t)
#define REMOVE_FROM_HASH_TABLE(t)
#define VALIDATE_NON_PENDING_TIMER(t)
@@ -283,6 +291,8 @@
gpr_free(g_shards);
gpr_free(g_shard_queue);
g_shared_mutables.initialized = false;
+
+ DESTROY_TIMER_HASH_TABLE();
}
/* returns true if the first element in the list */
@@ -336,9 +346,9 @@
#endif
if (grpc_timer_trace.enabled()) {
- gpr_log(GPR_DEBUG,
- "TIMER %p: SET %" PRIdPTR " now %" PRIdPTR " call %p[%p]", timer,
- deadline, grpc_core::ExecCtx::Get()->Now(), closure, closure->cb);
+ gpr_log(GPR_INFO, "TIMER %p: SET %" PRIdPTR " now %" PRIdPTR " call %p[%p]",
+ timer, deadline, grpc_core::ExecCtx::Get()->Now(), closure,
+ closure->cb);
}
if (!g_shared_mutables.initialized) {
@@ -372,7 +382,7 @@
list_join(&shard->list, timer);
}
if (grpc_timer_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
" .. add to shard %d with queue_deadline_cap=%" PRIdPTR
" => is_first_timer=%s",
static_cast<int>(shard - g_shards), shard->queue_deadline_cap,
@@ -394,7 +404,7 @@
if (is_first_timer) {
gpr_mu_lock(&g_shared_mutables.mu);
if (grpc_timer_trace.enabled()) {
- gpr_log(GPR_DEBUG, " .. old shard min_deadline=%" PRIdPTR,
+ gpr_log(GPR_INFO, " .. old shard min_deadline=%" PRIdPTR,
shard->min_deadline);
}
if (deadline < shard->min_deadline) {
@@ -424,7 +434,7 @@
timer_shard* shard = &g_shards[GPR_HASH_POINTER(timer, g_num_shards)];
gpr_mu_lock(&shard->mu);
if (grpc_timer_trace.enabled()) {
- gpr_log(GPR_DEBUG, "TIMER %p: CANCEL pending=%s", timer,
+ gpr_log(GPR_INFO, "TIMER %p: CANCEL pending=%s", timer,
timer->pending ? "true" : "false");
}
@@ -465,7 +475,7 @@
static_cast<gpr_atm>(deadline_delta * 1000.0));
if (grpc_timer_check_trace.enabled()) {
- gpr_log(GPR_DEBUG, " .. shard[%d]->queue_deadline_cap --> %" PRIdPTR,
+ gpr_log(GPR_INFO, " .. shard[%d]->queue_deadline_cap --> %" PRIdPTR,
static_cast<int>(shard - g_shards), shard->queue_deadline_cap);
}
for (timer = shard->list.next; timer != &shard->list; timer = next) {
@@ -473,7 +483,7 @@
if (timer->deadline < shard->queue_deadline_cap) {
if (grpc_timer_check_trace.enabled()) {
- gpr_log(GPR_DEBUG, " .. add timer with deadline %" PRIdPTR " to heap",
+ gpr_log(GPR_INFO, " .. add timer with deadline %" PRIdPTR " to heap",
timer->deadline);
}
list_remove(timer);
@@ -490,7 +500,7 @@
grpc_timer* timer;
for (;;) {
if (grpc_timer_check_trace.enabled()) {
- gpr_log(GPR_DEBUG, " .. shard[%d]: heap_empty=%s",
+ gpr_log(GPR_INFO, " .. shard[%d]: heap_empty=%s",
static_cast<int>(shard - g_shards),
grpc_timer_heap_is_empty(&shard->heap) ? "true" : "false");
}
@@ -500,13 +510,13 @@
}
timer = grpc_timer_heap_top(&shard->heap);
if (grpc_timer_check_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
" .. check top timer deadline=%" PRIdPTR " now=%" PRIdPTR,
timer->deadline, now);
}
if (timer->deadline > now) return nullptr;
if (grpc_timer_trace.enabled()) {
- gpr_log(GPR_DEBUG, "TIMER %p: FIRE %" PRIdPTR "ms late via %s scheduler",
+ gpr_log(GPR_INFO, "TIMER %p: FIRE %" PRIdPTR "ms late via %s scheduler",
timer, now - timer->deadline,
timer->closure->scheduler->vtable->name);
}
@@ -530,7 +540,7 @@
*new_min_deadline = compute_min_deadline(shard);
gpr_mu_unlock(&shard->mu);
if (grpc_timer_check_trace.enabled()) {
- gpr_log(GPR_DEBUG, " .. shard[%d] popped %" PRIdPTR,
+ gpr_log(GPR_INFO, " .. shard[%d] popped %" PRIdPTR,
static_cast<int>(shard - g_shards), n);
}
return n;
@@ -553,7 +563,7 @@
result = GRPC_TIMERS_CHECKED_AND_EMPTY;
if (grpc_timer_check_trace.enabled()) {
- gpr_log(GPR_DEBUG, " .. shard[%d]->min_deadline = %" PRIdPTR,
+ gpr_log(GPR_INFO, " .. shard[%d]->min_deadline = %" PRIdPTR,
static_cast<int>(g_shard_queue[0] - g_shards),
g_shard_queue[0]->min_deadline);
}
@@ -570,7 +580,7 @@
}
if (grpc_timer_check_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
" .. result --> %d"
", shard[%d]->min_deadline %" PRIdPTR " --> %" PRIdPTR
", now=%" PRIdPTR,
@@ -614,7 +624,7 @@
*next = GPR_MIN(*next, min_timer);
}
if (grpc_timer_check_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"TIMER CHECK SKIP: now=%" PRIdPTR " min_timer=%" PRIdPTR, now,
min_timer);
}
@@ -634,7 +644,7 @@
} else {
gpr_asprintf(&next_str, "%" PRIdPTR, *next);
}
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"TIMER CHECK BEGIN: now=%" PRIdPTR " next=%s tls_min=%" PRIdPTR
" glob_min=%" PRIdPTR,
now, next_str, gpr_tls_get(&g_last_seen_min_timer),
@@ -652,7 +662,7 @@
} else {
gpr_asprintf(&next_str, "%" PRIdPTR, *next);
}
- gpr_log(GPR_DEBUG, "TIMER CHECK END: r=%d; next=%s", r, next_str);
+ gpr_log(GPR_INFO, "TIMER CHECK END: r=%d; next=%s", r, next_str);
gpr_free(next_str);
}
return r;
diff --git a/src/core/lib/iomgr/timer_manager.cc b/src/core/lib/iomgr/timer_manager.cc
index 94f288a..35e7914 100644
--- a/src/core/lib/iomgr/timer_manager.cc
+++ b/src/core/lib/iomgr/timer_manager.cc
@@ -82,7 +82,7 @@
++g_thread_count;
gpr_mu_unlock(&g_mu);
if (grpc_timer_check_trace.enabled()) {
- gpr_log(GPR_DEBUG, "Spawn timer thread");
+ gpr_log(GPR_INFO, "Spawn timer thread");
}
completed_thread* ct =
static_cast<completed_thread*>(gpr_malloc(sizeof(*ct)));
@@ -108,7 +108,7 @@
// waiter so that the next deadline is not missed
if (!g_has_timed_waiter) {
if (grpc_timer_check_trace.enabled()) {
- gpr_log(GPR_DEBUG, "kick untimed waiter");
+ gpr_log(GPR_INFO, "kick untimed waiter");
}
gpr_cv_signal(&g_cv_wait);
}
@@ -116,7 +116,7 @@
}
// without our lock, flush the exec_ctx
if (grpc_timer_check_trace.enabled()) {
- gpr_log(GPR_DEBUG, "flush exec_ctx");
+ gpr_log(GPR_INFO, "flush exec_ctx");
}
grpc_core::ExecCtx::Get()->Flush();
gpr_mu_lock(&g_mu);
@@ -172,8 +172,7 @@
if (grpc_timer_check_trace.enabled()) {
grpc_millis wait_time = next - grpc_core::ExecCtx::Get()->Now();
- gpr_log(GPR_DEBUG, "sleep for a %" PRIdPTR " milliseconds",
- wait_time);
+ gpr_log(GPR_INFO, "sleep for a %" PRIdPTR " milliseconds", wait_time);
}
} else { // g_timed_waiter == true && next >= g_timed_waiter_deadline
next = GRPC_MILLIS_INF_FUTURE;
@@ -181,14 +180,14 @@
}
if (grpc_timer_check_trace.enabled() && next == GRPC_MILLIS_INF_FUTURE) {
- gpr_log(GPR_DEBUG, "sleep until kicked");
+ gpr_log(GPR_INFO, "sleep until kicked");
}
gpr_cv_wait(&g_cv_wait, &g_mu,
grpc_millis_to_timespec(next, GPR_CLOCK_MONOTONIC));
if (grpc_timer_check_trace.enabled()) {
- gpr_log(GPR_DEBUG, "wait ended: was_timed:%d kicked:%d",
+ gpr_log(GPR_INFO, "wait ended: was_timed:%d kicked:%d",
my_timed_waiter_generation == g_timed_waiter_generation,
g_kicked);
}
@@ -233,7 +232,7 @@
Consequently, we can just sleep forever here and be happy at some
saved wakeup cycles. */
if (grpc_timer_check_trace.enabled()) {
- gpr_log(GPR_DEBUG, "timers not checked: expect another thread to");
+ gpr_log(GPR_INFO, "timers not checked: expect another thread to");
}
next = GRPC_MILLIS_INF_FUTURE;
/* fall through */
@@ -259,7 +258,7 @@
g_completed_threads = ct;
gpr_mu_unlock(&g_mu);
if (grpc_timer_check_trace.enabled()) {
- gpr_log(GPR_DEBUG, "End timer thread");
+ gpr_log(GPR_INFO, "End timer thread");
}
}
@@ -301,18 +300,18 @@
static void stop_threads(void) {
gpr_mu_lock(&g_mu);
if (grpc_timer_check_trace.enabled()) {
- gpr_log(GPR_DEBUG, "stop timer threads: threaded=%d", g_threaded);
+ gpr_log(GPR_INFO, "stop timer threads: threaded=%d", g_threaded);
}
if (g_threaded) {
g_threaded = false;
gpr_cv_broadcast(&g_cv_wait);
if (grpc_timer_check_trace.enabled()) {
- gpr_log(GPR_DEBUG, "num timer threads: %d", g_thread_count);
+ gpr_log(GPR_INFO, "num timer threads: %d", g_thread_count);
}
while (g_thread_count > 0) {
gpr_cv_wait(&g_cv_shutdown, &g_mu, gpr_inf_future(GPR_CLOCK_MONOTONIC));
if (grpc_timer_check_trace.enabled()) {
- gpr_log(GPR_DEBUG, "num timer threads: %d", g_thread_count);
+ gpr_log(GPR_INFO, "num timer threads: %d", g_thread_count);
}
gc_completed_threads();
}
diff --git a/src/core/lib/iomgr/timer_uv.cc b/src/core/lib/iomgr/timer_uv.cc
index dadeb96..8b7c82e 100644
--- a/src/core/lib/iomgr/timer_uv.cc
+++ b/src/core/lib/iomgr/timer_uv.cc
@@ -52,6 +52,9 @@
uv_timer->data = t;
t->timer = (void*)uv_timer;
uv_timer_start(uv_timer, run_expired_timer, t->timeout_ms, 0);
+ // Node uses a garbage collector to call destructors, so we don't
+ // want to hold the uv loop open with active gRPC objects.
+ uv_unref((uv_handle_t*)uv_timer);
}
static void timer_stop(grpc_custom_timer* t) {
diff --git a/src/core/lib/iomgr/udp_server.cc b/src/core/lib/iomgr/udp_server.cc
index 04716a2..51d17eb 100644
--- a/src/core/lib/iomgr/udp_server.cc
+++ b/src/core/lib/iomgr/udp_server.cc
@@ -191,6 +191,9 @@
size_t pollset_count;
/* opaque object to pass to callbacks */
void* user_data;
+
+ /* latch has_so_reuseport during server creation */
+ bool so_reuseport;
};
static grpc_socket_factory* get_socket_factory(const grpc_channel_args* args) {
@@ -214,6 +217,7 @@
s->active_ports = 0;
s->destroyed_ports = 0;
s->shutdown = 0;
+ s->so_reuseport = grpc_is_socket_reuse_port_supported();
return s;
}
@@ -353,7 +357,7 @@
/* Prepare a recently-created socket for listening. */
static int prepare_socket(grpc_socket_factory* socket_factory, int fd,
const grpc_resolved_address* addr, int rcv_buf_size,
- int snd_buf_size) {
+ int snd_buf_size, bool so_reuseport) {
grpc_resolved_address sockname_temp;
grpc_sockaddr* addr_ptr =
reinterpret_cast<grpc_sockaddr*>(const_cast<char*>(addr->addr));
@@ -381,22 +385,6 @@
}
}
- GPR_ASSERT(addr->len < ~(socklen_t)0);
- if (bind_socket(socket_factory, fd, addr) < 0) {
- char* addr_str;
- grpc_sockaddr_to_string(&addr_str, addr, 0);
- gpr_log(GPR_ERROR, "bind addr=%s: %s", addr_str, strerror(errno));
- gpr_free(addr_str);
- goto error;
- }
-
- sockname_temp.len = static_cast<socklen_t>(sizeof(struct sockaddr_storage));
-
- if (getsockname(fd, reinterpret_cast<grpc_sockaddr*>(sockname_temp.addr),
- &sockname_temp.len) < 0) {
- goto error;
- }
-
if (grpc_set_socket_sndbuf(fd, snd_buf_size) != GRPC_ERROR_NONE) {
gpr_log(GPR_ERROR, "Failed to set send buffer size to %d bytes",
snd_buf_size);
@@ -416,6 +404,30 @@
gpr_log(GPR_INFO, "Failed to set socket overflow support");
}
}
+
+ if (so_reuseport && !grpc_is_unix_socket(addr) &&
+ grpc_set_socket_reuse_port(fd, 1) != GRPC_ERROR_NONE) {
+ gpr_log(GPR_ERROR, "Failed to set SO_REUSEPORT for fd %d", fd);
+ goto error;
+ }
+
+ if (bind_socket(socket_factory, fd, addr) < 0) {
+ char* addr_str;
+ grpc_sockaddr_to_string(&addr_str, addr, 0);
+ gpr_log(GPR_ERROR, "bind addr=%s: %s", addr_str, strerror(errno));
+ gpr_free(addr_str);
+ goto error;
+ }
+
+ sockname_temp.len = static_cast<socklen_t>(sizeof(struct sockaddr_storage));
+
+ if (getsockname(fd, reinterpret_cast<grpc_sockaddr*>(sockname_temp.addr),
+ &sockname_temp.len) < 0) {
+ gpr_log(GPR_ERROR, "Unable to get the address socket %d is bound to: %s",
+ fd, strerror(errno));
+ goto error;
+ }
+
return grpc_sockaddr_get_port(&sockname_temp);
error:
@@ -542,8 +554,8 @@
int rcv_buf_size, int snd_buf_size) {
gpr_log(GPR_DEBUG, "add socket %d to server", fd);
- int port =
- prepare_socket(s->socket_factory, fd, addr, rcv_buf_size, snd_buf_size);
+ int port = prepare_socket(s->socket_factory, fd, addr, rcv_buf_size,
+ snd_buf_size, s->so_reuseport);
if (port >= 0) {
gpr_mu_lock(&s->mu);
s->listeners.emplace_back(s, fd, addr);
@@ -558,7 +570,18 @@
int grpc_udp_server_add_port(grpc_udp_server* s,
const grpc_resolved_address* addr,
int rcv_buf_size, int snd_buf_size,
- GrpcUdpHandlerFactory* handler_factory) {
+ GrpcUdpHandlerFactory* handler_factory,
+ size_t num_listeners) {
+ if (num_listeners > 1 && !s->so_reuseport) {
+ gpr_log(GPR_ERROR,
+ "Try to have multiple listeners on same port, but SO_REUSEPORT is "
+ "not supported. Only create 1 listener.");
+ }
+ char* addr_str;
+ grpc_sockaddr_to_string(&addr_str, addr, 1);
+ gpr_log(GPR_DEBUG, "add address: %s to server", addr_str);
+ gpr_free(addr_str);
+
int allocated_port1 = -1;
int allocated_port2 = -1;
int fd;
@@ -569,11 +592,12 @@
grpc_resolved_address addr4_copy;
grpc_resolved_address* allocated_addr = nullptr;
grpc_resolved_address sockname_temp;
- int port;
+ int port = 0;
/* Check if this is a wildcard port, and if so, try to keep the port the same
as some previously created listener. */
if (grpc_sockaddr_get_port(addr) == 0) {
+ /* Loop through existing listeners to find the port in use. */
for (size_t i = 0; i < s->listeners.size(); ++i) {
sockname_temp.len =
static_cast<socklen_t>(sizeof(struct sockaddr_storage));
@@ -582,6 +606,7 @@
&sockname_temp.len)) {
port = grpc_sockaddr_get_port(&sockname_temp);
if (port > 0) {
+ /* Found such a port, update |addr| to reflects this port. */
allocated_addr = static_cast<grpc_resolved_address*>(
gpr_malloc(sizeof(grpc_resolved_address)));
memcpy(allocated_addr, addr, sizeof(grpc_resolved_address));
@@ -598,44 +623,73 @@
}
s->handler_factory = handler_factory;
- /* Treat :: or 0.0.0.0 as a family-agnostic wildcard. */
- if (grpc_sockaddr_is_wildcard(addr, &port)) {
- grpc_sockaddr_make_wildcards(port, &wild4, &wild6);
+ for (size_t i = 0; i < num_listeners; ++i) {
+ /* Treat :: or 0.0.0.0 as a family-agnostic wildcard. */
+ if (grpc_sockaddr_is_wildcard(addr, &port)) {
+ grpc_sockaddr_make_wildcards(port, &wild4, &wild6);
- /* Try listening on IPv6 first. */
- addr = &wild6;
+ /* Try listening on IPv6 first. */
+ addr = &wild6;
+ // TODO(rjshade): Test and propagate the returned grpc_error*:
+ GRPC_ERROR_UNREF(grpc_create_dualstack_socket_using_factory(
+ s->socket_factory, addr, SOCK_DGRAM, IPPROTO_UDP, &dsmode, &fd));
+ allocated_port1 =
+ add_socket_to_server(s, fd, addr, rcv_buf_size, snd_buf_size);
+ if (fd >= 0 && dsmode == GRPC_DSMODE_DUALSTACK) {
+ if (port == 0) {
+ /* This is the first time to bind to |addr|. If its port is still
+ * wildcard port, update |addr| with the ephermeral port returned by
+ * kernel. Thus |addr| can have a specific port in following
+ * iterations. */
+ grpc_sockaddr_set_port(addr, allocated_port1);
+ port = allocated_port1;
+ } else if (allocated_port1 >= 0) {
+ /* The following sucessfully created socket should have same port as
+ * the first one. */
+ GPR_ASSERT(port == allocated_port1);
+ }
+ /* A dualstack socket is created, no need to create corresponding IPV4
+ * socket. */
+ continue;
+ }
+
+ /* If we didn't get a dualstack socket, also listen on 0.0.0.0. */
+ if (port == 0 && allocated_port1 > 0) {
+ /* |port| hasn't been assigned to an emphemeral port yet, |wild4| must
+ * have a wildcard port. Update it with the emphemeral port created
+ * during binding.*/
+ grpc_sockaddr_set_port(&wild4, allocated_port1);
+ port = allocated_port1;
+ }
+ /* |wild4| should have been updated with an emphemeral port by now. Use
+ * this IPV4 address to create a IPV4 socket. */
+ addr = &wild4;
+ }
+
// TODO(rjshade): Test and propagate the returned grpc_error*:
GRPC_ERROR_UNREF(grpc_create_dualstack_socket_using_factory(
s->socket_factory, addr, SOCK_DGRAM, IPPROTO_UDP, &dsmode, &fd));
- allocated_port1 =
+ if (fd < 0) {
+ gpr_log(GPR_ERROR, "Unable to create socket: %s", strerror(errno));
+ }
+ if (dsmode == GRPC_DSMODE_IPV4 &&
+ grpc_sockaddr_is_v4mapped(addr, &addr4_copy)) {
+ addr = &addr4_copy;
+ }
+ allocated_port2 =
add_socket_to_server(s, fd, addr, rcv_buf_size, snd_buf_size);
- if (fd >= 0 && dsmode == GRPC_DSMODE_DUALSTACK) {
- goto done;
+ if (port == 0) {
+ /* Update |addr| with the ephermeral port returned by kernel. So |addr|
+ * can have a specific port in following iterations. */
+ grpc_sockaddr_set_port(addr, allocated_port2);
+ port = allocated_port2;
+ } else if (allocated_port2 >= 0) {
+ GPR_ASSERT(port == allocated_port2);
}
-
- /* If we didn't get a dualstack socket, also listen on 0.0.0.0. */
- if (port == 0 && allocated_port1 > 0) {
- grpc_sockaddr_set_port(&wild4, allocated_port1);
- }
- addr = &wild4;
}
- // TODO(rjshade): Test and propagate the returned grpc_error*:
- GRPC_ERROR_UNREF(grpc_create_dualstack_socket_using_factory(
- s->socket_factory, addr, SOCK_DGRAM, IPPROTO_UDP, &dsmode, &fd));
- if (fd < 0) {
- gpr_log(GPR_ERROR, "Unable to create socket: %s", strerror(errno));
- }
- if (dsmode == GRPC_DSMODE_IPV4 &&
- grpc_sockaddr_is_v4mapped(addr, &addr4_copy)) {
- addr = &addr4_copy;
- }
- allocated_port2 =
- add_socket_to_server(s, fd, addr, rcv_buf_size, snd_buf_size);
-
-done:
gpr_free(allocated_addr);
- return allocated_port1 >= 0 ? allocated_port1 : allocated_port2;
+ return port;
}
int grpc_udp_server_get_fd(grpc_udp_server* s, unsigned port_index) {
diff --git a/src/core/lib/iomgr/udp_server.h b/src/core/lib/iomgr/udp_server.h
index 4e384d2..3656791 100644
--- a/src/core/lib/iomgr/udp_server.h
+++ b/src/core/lib/iomgr/udp_server.h
@@ -86,17 +86,21 @@
/* Add a port to the server, returning port number on success, or negative
on failure.
+ Create |num_listeners| sockets for given address to listen on using
+ SO_REUSEPORT if supported.
+
The :: and 0.0.0.0 wildcard addresses are treated identically, accepting
- both IPv4 and IPv6 connections, but :: is the preferred style. This usually
- creates one socket, but possibly two on systems which support IPv6,
- but not dualstack sockets. */
+ both IPv4 and IPv6 connections, but :: is the preferred style. This usually
+ creates |num_listeners| sockets, but possibly 2 * |num_listeners| on systems
+ which support IPv6, but not dualstack sockets. */
/* TODO(ctiller): deprecate this, and make grpc_udp_server_add_ports to handle
all of the multiple socket port matching logic in one place */
int grpc_udp_server_add_port(grpc_udp_server* s,
const grpc_resolved_address* addr,
int rcv_buf_size, int snd_buf_size,
- GrpcUdpHandlerFactory* handler_factory);
+ GrpcUdpHandlerFactory* handler_factory,
+ size_t num_listeners);
void grpc_udp_server_destroy(grpc_udp_server* server, grpc_closure* on_done);
diff --git a/src/core/lib/profiling/basic_timers.cc b/src/core/lib/profiling/basic_timers.cc
index 652a498..b19ad9f 100644
--- a/src/core/lib/profiling/basic_timers.cc
+++ b/src/core/lib/profiling/basic_timers.cc
@@ -27,6 +27,7 @@
#include <grpc/support/sync.h>
#include <grpc/support/time.h>
#include <inttypes.h>
+#include <pthread.h>
#include <stdio.h>
#include <string.h>
diff --git a/src/core/lib/security/credentials/alts/alts_credentials.h b/src/core/lib/security/credentials/alts/alts_credentials.h
index 621789c..810117f 100644
--- a/src/core/lib/security/credentials/alts/alts_credentials.h
+++ b/src/core/lib/security/credentials/alts/alts_credentials.h
@@ -41,26 +41,6 @@
} grpc_alts_server_credentials;
/**
- * This method creates an ALTS channel credential object.
- *
- * - options: grpc ALTS credentials options instance for client.
- *
- * It returns the created ALTS channel credential object.
- */
-grpc_channel_credentials* grpc_alts_credentials_create(
- const grpc_alts_credentials_options* options);
-
-/**
- * This method creates an ALTS server credential object.
- *
- * - options: grpc ALTS credentials options instance for server.
- *
- * It returns the created ALTS server credential object.
- */
-grpc_server_credentials* grpc_alts_server_credentials_create(
- const grpc_alts_credentials_options* options);
-
-/**
* This method creates an ALTS channel credential object with customized
* information provided by caller.
*
diff --git a/src/core/lib/security/credentials/alts/grpc_alts_credentials_client_options.cc b/src/core/lib/security/credentials/alts/grpc_alts_credentials_client_options.cc
index 7d54e83..0a39c6c 100644
--- a/src/core/lib/security/credentials/alts/grpc_alts_credentials_client_options.cc
+++ b/src/core/lib/security/credentials/alts/grpc_alts_credentials_client_options.cc
@@ -44,20 +44,20 @@
return sa;
}
-bool grpc_alts_credentials_client_options_add_target_service_account(
- grpc_alts_credentials_client_options* options,
- const char* service_account) {
+void grpc_alts_credentials_client_options_add_target_service_account(
+ grpc_alts_credentials_options* options, const char* service_account) {
if (options == nullptr || service_account == nullptr) {
gpr_log(
GPR_ERROR,
"Invalid nullptr arguments to "
"grpc_alts_credentials_client_options_add_target_service_account()");
- return false;
+ return;
}
+ auto client_options =
+ reinterpret_cast<grpc_alts_credentials_client_options*>(options);
target_service_account* node = target_service_account_create(service_account);
- node->next = options->target_account_list_head;
- options->target_account_list_head = node;
- return true;
+ node->next = client_options->target_account_list_head;
+ client_options->target_account_list_head = node;
}
static void target_service_account_destroy(
diff --git a/src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h b/src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h
index 4e46d9f..320af71 100644
--- a/src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h
+++ b/src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h
@@ -21,19 +21,10 @@
#include <grpc/support/port_platform.h>
-#include <stdbool.h>
+#include <grpc/grpc_security.h>
#include "src/core/tsi/alts/handshaker/transport_security_common_api.h"
-/**
- * Main interface for ALTS credentials options. The options will contain
- * information that will be passed from grpc to TSI layer such as RPC protocol
- * versions. ALTS client (channel) and server credentials will have their own
- * implementation of this interface. The APIs listed in this header are
- * thread-compatible.
- */
-typedef struct grpc_alts_credentials_options grpc_alts_credentials_options;
-
/* V-table for grpc_alts_credentials_options */
typedef struct grpc_alts_credentials_options_vtable {
grpc_alts_credentials_options* (*copy)(
@@ -80,33 +71,5 @@
grpc_alts_credentials_options* grpc_alts_credentials_options_copy(
const grpc_alts_credentials_options* options);
-/**
- * This method destroys a grpc_alts_credentials_options instance by
- * de-allocating all of its occupied memory.
- *
- * - options: a grpc_alts_credentials_options instance that needs to be
- * destroyed.
- */
-void grpc_alts_credentials_options_destroy(
- grpc_alts_credentials_options* options);
-
-/* This method creates a grpc ALTS credentials client options instance. */
-grpc_alts_credentials_options* grpc_alts_credentials_client_options_create();
-
-/* This method creates a grpc ALTS credentials server options instance. */
-grpc_alts_credentials_options* grpc_alts_credentials_server_options_create();
-
-/**
- * This method adds a target service account to grpc ALTS credentials client
- * options instance.
- *
- * - options: grpc ALTS credentials client options instance.
- * - service_account: service account of target endpoint.
- *
- * It returns true on success and false on failure.
- */
-bool grpc_alts_credentials_client_options_add_target_service_account(
- grpc_alts_credentials_client_options* options, const char* service_account);
-
#endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_ALTS_GRPC_ALTS_CREDENTIALS_OPTIONS_H \
*/
diff --git a/src/core/lib/security/credentials/credentials.h b/src/core/lib/security/credentials/credentials.h
index b1421e8..b486d25 100644
--- a/src/core/lib/security/credentials/credentials.h
+++ b/src/core/lib/security/credentials/credentials.h
@@ -45,6 +45,7 @@
#define GRPC_CHANNEL_CREDENTIALS_TYPE_SSL "Ssl"
#define GRPC_CHANNEL_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY \
"FakeTransportSecurity"
+#define GRPC_CHANNEL_CREDENTIALS_TYPE_GOOGLE_DEFAULT "GoogleDefault"
#define GRPC_CALL_CREDENTIALS_TYPE_OAUTH2 "Oauth2"
#define GRPC_CALL_CREDENTIALS_TYPE_JWT "Jwt"
diff --git a/src/core/lib/security/credentials/google_default/google_default_credentials.cc b/src/core/lib/security/credentials/google_default/google_default_credentials.cc
index 70d4c3e..4b267af 100644
--- a/src/core/lib/security/credentials/google_default/google_default_credentials.cc
+++ b/src/core/lib/security/credentials/google_default/google_default_credentials.cc
@@ -26,12 +26,15 @@
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
+#include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h"
+#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/http/httpcli.h"
#include "src/core/lib/http/parser.h"
#include "src/core/lib/iomgr/load_file.h"
#include "src/core/lib/iomgr/polling_entity.h"
+#include "src/core/lib/security/credentials/alts/alts_credentials.h"
#include "src/core/lib/security/credentials/google_default/google_default_credentials.h"
#include "src/core/lib/security/credentials/jwt/jwt_credentials.h"
#include "src/core/lib/security/credentials/oauth2/oauth2_credentials.h"
@@ -45,8 +48,8 @@
/* -- Default credentials. -- */
-static grpc_channel_credentials* default_credentials = nullptr;
-static int compute_engine_detection_done = 0;
+static grpc_channel_credentials* g_default_credentials = nullptr;
+static int g_compute_engine_detection_done = 0;
static gpr_mu g_state_mu;
static gpr_mu* g_polling_mu;
static gpr_once g_once = GPR_ONCE_INIT;
@@ -60,6 +63,52 @@
grpc_http_response response;
} compute_engine_detector;
+static void google_default_credentials_destruct(
+ grpc_channel_credentials* creds) {
+ grpc_google_default_channel_credentials* c =
+ reinterpret_cast<grpc_google_default_channel_credentials*>(creds);
+ grpc_channel_credentials_unref(c->alts_creds);
+ grpc_channel_credentials_unref(c->ssl_creds);
+}
+
+static grpc_security_status google_default_create_security_connector(
+ grpc_channel_credentials* creds, grpc_call_credentials* call_creds,
+ const char* target, const grpc_channel_args* args,
+ grpc_channel_security_connector** sc, grpc_channel_args** new_args) {
+ grpc_google_default_channel_credentials* c =
+ reinterpret_cast<grpc_google_default_channel_credentials*>(creds);
+ bool is_grpclb_load_balancer = grpc_channel_arg_get_bool(
+ grpc_channel_args_find(args, GRPC_ARG_ADDRESS_IS_GRPCLB_LOAD_BALANCER),
+ false);
+ bool is_backend_from_grpclb_load_balancer = grpc_channel_arg_get_bool(
+ grpc_channel_args_find(
+ args, GRPC_ARG_ADDRESS_IS_BACKEND_FROM_GRPCLB_LOAD_BALANCER),
+ false);
+ bool use_alts =
+ is_grpclb_load_balancer || is_backend_from_grpclb_load_balancer;
+ grpc_security_status status = GRPC_SECURITY_ERROR;
+ status = use_alts ? c->alts_creds->vtable->create_security_connector(
+ c->alts_creds, call_creds, target, args, sc, new_args)
+ : c->ssl_creds->vtable->create_security_connector(
+ c->ssl_creds, call_creds, target, args, sc, new_args);
+ /* grpclb-specific channel args are removed from the channel args set
+ * to ensure backends and fallback adresses will have the same set of channel
+ * args. By doing that, it guarantees the connections to backends will not be
+ * torn down and re-connected when switching in and out of fallback mode.
+ */
+ static const char* args_to_remove[] = {
+ GRPC_ARG_ADDRESS_IS_GRPCLB_LOAD_BALANCER,
+ GRPC_ARG_ADDRESS_IS_BACKEND_FROM_GRPCLB_LOAD_BALANCER,
+ };
+ *new_args = grpc_channel_args_copy_and_add_and_remove(
+ args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), nullptr, 0);
+ return status;
+}
+
+static grpc_channel_credentials_vtable google_default_credentials_vtable = {
+ google_default_credentials_destruct,
+ google_default_create_security_connector, nullptr};
+
static void on_compute_engine_detection_http_response(void* user_data,
grpc_error* error) {
compute_engine_detector* detector =
@@ -234,8 +283,8 @@
gpr_mu_lock(&g_state_mu);
- if (default_credentials != nullptr) {
- result = grpc_channel_credentials_ref(default_credentials);
+ if (g_default_credentials != nullptr) {
+ result = grpc_channel_credentials_ref(g_default_credentials);
goto end;
}
@@ -253,9 +302,9 @@
/* At last try to see if we're on compute engine (do the detection only once
since it requires a network test). */
- if (!compute_engine_detection_done) {
+ if (!g_compute_engine_detection_done) {
int need_compute_engine_creds = is_stack_running_on_compute_engine();
- compute_engine_detection_done = 1;
+ g_compute_engine_detection_done = 1;
if (need_compute_engine_creds) {
call_creds = grpc_google_compute_engine_credentials_create(nullptr);
if (call_creds == nullptr) {
@@ -269,18 +318,25 @@
end:
if (result == nullptr) {
if (call_creds != nullptr) {
- /* Blend with default ssl credentials and add a global reference so that
- it
- can be cached and re-served. */
- grpc_channel_credentials* ssl_creds =
- grpc_ssl_credentials_create(nullptr, nullptr, nullptr);
- default_credentials = grpc_channel_credentials_ref(
- grpc_composite_channel_credentials_create(ssl_creds, call_creds,
- nullptr));
- GPR_ASSERT(default_credentials != nullptr);
- grpc_channel_credentials_unref(ssl_creds);
+ /* Create google default credentials. */
+ auto creds = static_cast<grpc_google_default_channel_credentials*>(
+ gpr_zalloc(sizeof(grpc_google_default_channel_credentials)));
+ creds->base.vtable = &google_default_credentials_vtable;
+ creds->base.type = GRPC_CHANNEL_CREDENTIALS_TYPE_GOOGLE_DEFAULT;
+ gpr_ref_init(&creds->base.refcount, 1);
+ creds->ssl_creds = grpc_ssl_credentials_create(nullptr, nullptr, nullptr);
+ GPR_ASSERT(creds->ssl_creds != nullptr);
+ grpc_alts_credentials_options* options =
+ grpc_alts_credentials_client_options_create();
+ creds->alts_creds = grpc_alts_credentials_create(options);
+ grpc_alts_credentials_options_destroy(options);
+ /* Add a global reference so that it can be cached and re-served. */
+ g_default_credentials = grpc_composite_channel_credentials_create(
+ &creds->base, call_creds, nullptr);
+ GPR_ASSERT(g_default_credentials != nullptr);
+ grpc_channel_credentials_unref(&creds->base);
grpc_call_credentials_unref(call_creds);
- result = default_credentials;
+ result = grpc_channel_credentials_ref(g_default_credentials);
} else {
gpr_log(GPR_ERROR, "Could not create google default credentials.");
}
@@ -299,11 +355,11 @@
grpc_core::ExecCtx exec_ctx;
gpr_once_init(&g_once, init_default_credentials);
gpr_mu_lock(&g_state_mu);
- if (default_credentials != nullptr) {
- grpc_channel_credentials_unref(default_credentials);
- default_credentials = nullptr;
+ if (g_default_credentials != nullptr) {
+ grpc_channel_credentials_unref(g_default_credentials);
+ g_default_credentials = nullptr;
}
- compute_engine_detection_done = 0;
+ g_compute_engine_detection_done = 0;
gpr_mu_unlock(&g_state_mu);
}
diff --git a/src/core/lib/security/credentials/google_default/google_default_credentials.h b/src/core/lib/security/credentials/google_default/google_default_credentials.h
index b163e48..9b4063c 100644
--- a/src/core/lib/security/credentials/google_default/google_default_credentials.h
+++ b/src/core/lib/security/credentials/google_default/google_default_credentials.h
@@ -39,6 +39,12 @@
"/" GRPC_GOOGLE_WELL_KNOWN_CREDENTIALS_FILE
#endif
+typedef struct {
+ grpc_channel_credentials base;
+ grpc_channel_credentials* alts_creds;
+ grpc_channel_credentials* ssl_creds;
+} grpc_google_default_channel_credentials;
+
void grpc_flush_cached_google_default_credentials(void);
#endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_GOOGLE_DEFAULT_GOOGLE_DEFAULT_CREDENTIALS_H \
diff --git a/src/core/lib/security/security_connector/security_connector.cc b/src/core/lib/security/security_connector/security_connector.cc
index 3967112..a306967 100644
--- a/src/core/lib/security/security_connector/security_connector.cc
+++ b/src/core/lib/security/security_connector/security_connector.cc
@@ -44,7 +44,6 @@
#include "src/core/lib/security/transport/target_authority_table.h"
#include "src/core/tsi/fake_transport_security.h"
#include "src/core/tsi/ssl_transport_security.h"
-#include "src/core/tsi/transport_security_adapter.h"
grpc_core::DebugOnlyTraceFlag grpc_trace_security_connector_refcount(
false, "security_connector_refcount");
@@ -306,6 +305,7 @@
char* target;
char* expected_targets;
bool is_lb_channel;
+ char* target_name_override;
} grpc_fake_channel_security_connector;
static void fake_channel_destroy(grpc_security_connector* sc) {
@@ -314,6 +314,7 @@
grpc_call_credentials_unref(c->base.request_metadata_creds);
gpr_free(c->target);
gpr_free(c->expected_targets);
+ gpr_free(c->target_name_override);
gpr_free(c);
}
@@ -465,13 +466,36 @@
grpc_error** error) {
grpc_fake_channel_security_connector* c =
reinterpret_cast<grpc_fake_channel_security_connector*>(sc);
- if (c->is_lb_channel) {
- // TODO(dgq): verify that the host (ie, authority header) matches that of
- // the LB, as opposed to that of the backends.
- } else {
- // TODO(dgq): verify that the host (ie, authority header) matches that of
- // the backend, not the LB's.
+ char* authority_hostname = nullptr;
+ char* authority_ignored_port = nullptr;
+ char* target_hostname = nullptr;
+ char* target_ignored_port = nullptr;
+ gpr_split_host_port(host, &authority_hostname, &authority_ignored_port);
+ gpr_split_host_port(c->target, &target_hostname, &target_ignored_port);
+ if (c->target_name_override != nullptr) {
+ char* fake_security_target_name_override_hostname = nullptr;
+ char* fake_security_target_name_override_ignored_port = nullptr;
+ gpr_split_host_port(c->target_name_override,
+ &fake_security_target_name_override_hostname,
+ &fake_security_target_name_override_ignored_port);
+ if (strcmp(authority_hostname,
+ fake_security_target_name_override_hostname) != 0) {
+ gpr_log(GPR_ERROR,
+ "Authority (host) '%s' != Fake Security Target override '%s'",
+ host, fake_security_target_name_override_hostname);
+ abort();
+ }
+ gpr_free(fake_security_target_name_override_hostname);
+ gpr_free(fake_security_target_name_override_ignored_port);
+ } else if (strcmp(authority_hostname, target_hostname) != 0) {
+ gpr_log(GPR_ERROR, "Authority (host) '%s' != Target '%s'",
+ authority_hostname, target_hostname);
+ abort();
}
+ gpr_free(authority_hostname);
+ gpr_free(authority_ignored_port);
+ gpr_free(target_hostname);
+ gpr_free(target_ignored_port);
return true;
}
@@ -524,6 +548,12 @@
const char* expected_targets = grpc_fake_transport_get_expected_targets(args);
c->expected_targets = gpr_strdup(expected_targets);
c->is_lb_channel = grpc_core::FindTargetAuthorityTableInArgs(args) != nullptr;
+ const grpc_arg* target_name_override_arg =
+ grpc_channel_args_find(args, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG);
+ if (target_name_override_arg != nullptr) {
+ c->target_name_override =
+ gpr_strdup(grpc_channel_arg_get_string(target_name_override_arg));
+ }
return &c->base;
}
@@ -642,8 +672,7 @@
}
// Create handshakers.
grpc_handshake_manager_add(
- handshake_mgr, grpc_security_handshaker_create(
- tsi_create_adapter_handshaker(tsi_hs), &sc->base));
+ handshake_mgr, grpc_security_handshaker_create(tsi_hs, &sc->base));
}
static const char** fill_alpn_protocol_strings(size_t* num_alpn_protocols) {
@@ -751,27 +780,29 @@
}
// Create handshakers.
grpc_handshake_manager_add(
- handshake_mgr, grpc_security_handshaker_create(
- tsi_create_adapter_handshaker(tsi_hs), &sc->base));
+ handshake_mgr, grpc_security_handshaker_create(tsi_hs, &sc->base));
}
-static int ssl_host_matches_name(const tsi_peer* peer, const char* peer_name) {
+int grpc_ssl_host_matches_name(const tsi_peer* peer, const char* peer_name) {
char* allocated_name = nullptr;
int r;
- if (strchr(peer_name, ':') != nullptr) {
- char* ignored_port;
- gpr_split_host_port(peer_name, &allocated_name, &ignored_port);
- gpr_free(ignored_port);
- peer_name = allocated_name;
- if (!peer_name) return 0;
- }
+ char* ignored_port;
+ gpr_split_host_port(peer_name, &allocated_name, &ignored_port);
+ gpr_free(ignored_port);
+ peer_name = allocated_name;
+ if (!peer_name) return 0;
+
+ // IPv6 zone-id should not be included in comparisons.
+ char* const zone_id = strchr(allocated_name, '%');
+ if (zone_id != nullptr) *zone_id = '\0';
+
r = tsi_ssl_peer_matches_name(peer, peer_name);
gpr_free(allocated_name);
return r;
}
-grpc_auth_context* tsi_ssl_peer_to_auth_context(const tsi_peer* peer) {
+grpc_auth_context* grpc_ssl_peer_to_auth_context(const tsi_peer* peer) {
size_t i;
grpc_auth_context* ctx = nullptr;
const char* peer_identity_property_name = nullptr;
@@ -828,14 +859,14 @@
}
/* Check the peer name if specified. */
- if (peer_name != nullptr && !ssl_host_matches_name(peer, peer_name)) {
+ if (peer_name != nullptr && !grpc_ssl_host_matches_name(peer, peer_name)) {
char* msg;
gpr_asprintf(&msg, "Peer name %s is not in peer certificate", peer_name);
grpc_error* error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
gpr_free(msg);
return error;
}
- *auth_context = tsi_ssl_peer_to_auth_context(peer);
+ *auth_context = grpc_ssl_peer_to_auth_context(peer);
return GRPC_ERROR_NONE;
}
@@ -893,7 +924,7 @@
tsi_prop->value.length = prop->value_length;
}
-tsi_peer tsi_shallow_peer_from_ssl_auth_context(
+tsi_peer grpc_shallow_peer_from_ssl_auth_context(
const grpc_auth_context* auth_context) {
size_t max_num_props = 0;
grpc_auth_property_iterator it;
@@ -924,7 +955,7 @@
return peer;
}
-void tsi_shallow_peer_destruct(tsi_peer* peer) {
+void grpc_shallow_peer_destruct(tsi_peer* peer) {
if (peer->properties != nullptr) gpr_free(peer->properties);
}
@@ -936,8 +967,8 @@
grpc_ssl_channel_security_connector* c =
reinterpret_cast<grpc_ssl_channel_security_connector*>(sc);
grpc_security_status status = GRPC_SECURITY_ERROR;
- tsi_peer peer = tsi_shallow_peer_from_ssl_auth_context(auth_context);
- if (ssl_host_matches_name(&peer, host)) status = GRPC_SECURITY_OK;
+ tsi_peer peer = grpc_shallow_peer_from_ssl_auth_context(auth_context);
+ if (grpc_ssl_host_matches_name(&peer, host)) status = GRPC_SECURITY_OK;
/* If the target name was overridden, then the original target_name was
'checked' transitively during the previous peer check at the end of the
handshake. */
@@ -949,7 +980,7 @@
*error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"call host does not match SSL server name");
}
- tsi_shallow_peer_destruct(&peer);
+ grpc_shallow_peer_destruct(&peer);
return true;
}
@@ -1120,16 +1151,6 @@
GRPC_SLICE_START_PTR(default_pem_root_certs_);
}
-void DefaultSslRootStore::Initialize() {
- default_root_store_ = nullptr;
- default_pem_root_certs_ = grpc_empty_slice();
-}
-
-void DefaultSslRootStore::Destroy() {
- tsi_ssl_root_certs_store_destroy(default_root_store_);
- grpc_slice_unref_internal(default_pem_root_certs_);
-}
-
grpc_slice DefaultSslRootStore::ComputePemRootCerts() {
grpc_slice result = grpc_empty_slice();
// First try to load the roots from the environment.
diff --git a/src/core/lib/security/security_connector/security_connector.h b/src/core/lib/security/security_connector/security_connector.h
index 5d3d1e0..f972316 100644
--- a/src/core/lib/security/security_connector/security_connector.h
+++ b/src/core/lib/security/security_connector/security_connector.h
@@ -239,10 +239,11 @@
const char* name);
/* Exposed for testing only. */
-grpc_auth_context* tsi_ssl_peer_to_auth_context(const tsi_peer* peer);
-tsi_peer tsi_shallow_peer_from_ssl_auth_context(
+grpc_auth_context* grpc_ssl_peer_to_auth_context(const tsi_peer* peer);
+tsi_peer grpc_shallow_peer_from_ssl_auth_context(
const grpc_auth_context* auth_context);
-void tsi_shallow_peer_destruct(tsi_peer* peer);
+void grpc_shallow_peer_destruct(tsi_peer* peer);
+int grpc_ssl_host_matches_name(const tsi_peer* peer, const char* peer_name);
/* --- Default SSL Root Store. --- */
namespace grpc_core {
@@ -256,15 +257,6 @@
// Gets the default PEM root certificate.
static const char* GetPemRootCerts();
- // Initializes the SSL root store's underlying data structure. It does not
- // load default SSL root certificates. Should only be called by
- // grpc_security_init().
- static void Initialize();
-
- // Destroys the default SSL root store. Should only be called by
- // grpc_security_shutdown().
- static void Destroy();
-
protected:
// Returns default PEM root certificates in nullptr terminated grpc_slice.
// This function is protected instead of private, so that it can be tested.
diff --git a/src/core/lib/security/transport/secure_endpoint.cc b/src/core/lib/security/transport/secure_endpoint.cc
index 31b779e..840b2e7 100644
--- a/src/core/lib/security/transport/secure_endpoint.cc
+++ b/src/core/lib/security/transport/secure_endpoint.cc
@@ -133,7 +133,7 @@
for (i = 0; i < ep->read_buffer->count; i++) {
char* data = grpc_dump_slice(ep->read_buffer->slices[i],
GPR_DUMP_HEX | GPR_DUMP_ASCII);
- gpr_log(GPR_DEBUG, "READ %p: %s", ep, data);
+ gpr_log(GPR_INFO, "READ %p: %s", ep, data);
gpr_free(data);
}
}
@@ -269,7 +269,7 @@
for (i = 0; i < slices->count; i++) {
char* data =
grpc_dump_slice(slices->slices[i], GPR_DUMP_HEX | GPR_DUMP_ASCII);
- gpr_log(GPR_DEBUG, "WRITE %p: %s", ep, data);
+ gpr_log(GPR_INFO, "WRITE %p: %s", ep, data);
gpr_free(data);
}
}
diff --git a/src/core/lib/security/transport/security_handshaker.cc b/src/core/lib/security/transport/security_handshaker.cc
index 0c97dfa..aff723e 100644
--- a/src/core/lib/security/transport/security_handshaker.cc
+++ b/src/core/lib/security/transport/security_handshaker.cc
@@ -232,6 +232,10 @@
const unsigned char* bytes_to_send, size_t bytes_to_send_size,
tsi_handshaker_result* handshaker_result) {
grpc_error* error = GRPC_ERROR_NONE;
+ // Handshaker was shutdown.
+ if (h->shutdown) {
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Handshaker shutdown");
+ }
// Read more if we need to.
if (result == TSI_INCOMPLETE_DATA) {
GPR_ASSERT(bytes_to_send_size == 0);
@@ -376,6 +380,7 @@
gpr_mu_lock(&h->mu);
if (!h->shutdown) {
h->shutdown = true;
+ tsi_handshaker_shutdown(h->handshaker);
grpc_endpoint_shutdown(h->args->endpoint, GRPC_ERROR_REF(why));
cleanup_args_for_failure_locked(h);
}
@@ -406,7 +411,7 @@
static const grpc_handshaker_vtable security_handshaker_vtable = {
security_handshaker_destroy, security_handshaker_shutdown,
- security_handshaker_do_handshake};
+ security_handshaker_do_handshake, "security"};
static grpc_handshaker* security_handshaker_create(
tsi_handshaker* handshaker, grpc_security_connector* connector) {
@@ -456,7 +461,7 @@
static const grpc_handshaker_vtable fail_handshaker_vtable = {
fail_handshaker_destroy, fail_handshaker_shutdown,
- fail_handshaker_do_handshake};
+ fail_handshaker_do_handshake, "security_fail"};
static grpc_handshaker* fail_handshaker_create() {
grpc_handshaker* h = static_cast<grpc_handshaker*>(gpr_malloc(sizeof(*h)));
diff --git a/src/core/lib/slice/slice.cc b/src/core/lib/slice/slice.cc
index 585b41c..4194741 100644
--- a/src/core/lib/slice/slice.cc
+++ b/src/core/lib/slice/slice.cc
@@ -69,8 +69,12 @@
/* Public API */
void grpc_slice_unref(grpc_slice slice) {
- grpc_core::ExecCtx exec_ctx;
- grpc_slice_unref_internal(slice);
+ if (grpc_core::ExecCtx::Get() == nullptr) {
+ grpc_core::ExecCtx exec_ctx;
+ grpc_slice_unref_internal(slice);
+ } else {
+ grpc_slice_unref_internal(slice);
+ }
}
/* grpc_slice_from_static_string support structure - a refcount that does
diff --git a/src/core/lib/slice/slice_buffer.cc b/src/core/lib/slice/slice_buffer.cc
index 58ca495..fd56997 100644
--- a/src/core/lib/slice/slice_buffer.cc
+++ b/src/core/lib/slice/slice_buffer.cc
@@ -75,8 +75,12 @@
}
void grpc_slice_buffer_destroy(grpc_slice_buffer* sb) {
- grpc_core::ExecCtx exec_ctx;
- grpc_slice_buffer_destroy_internal(sb);
+ if (grpc_core::ExecCtx::Get() == nullptr) {
+ grpc_core::ExecCtx exec_ctx;
+ grpc_slice_buffer_destroy_internal(sb);
+ } else {
+ grpc_slice_buffer_destroy_internal(sb);
+ }
}
uint8_t* grpc_slice_buffer_tiny_add(grpc_slice_buffer* sb, size_t n) {
@@ -176,8 +180,12 @@
}
void grpc_slice_buffer_reset_and_unref(grpc_slice_buffer* sb) {
- grpc_core::ExecCtx exec_ctx;
- grpc_slice_buffer_reset_and_unref_internal(sb);
+ if (grpc_core::ExecCtx::Get() == nullptr) {
+ grpc_core::ExecCtx exec_ctx;
+ grpc_slice_buffer_reset_and_unref_internal(sb);
+ } else {
+ grpc_slice_buffer_reset_and_unref_internal(sb);
+ }
}
void grpc_slice_buffer_swap(grpc_slice_buffer* a, grpc_slice_buffer* b) {
diff --git a/src/core/lib/slice/slice_hash_table.h b/src/core/lib/slice/slice_hash_table.h
index fbe9cc5..4bbcf88 100644
--- a/src/core/lib/slice/slice_hash_table.h
+++ b/src/core/lib/slice/slice_hash_table.h
@@ -81,6 +81,10 @@
template <typename T2, typename... Args>
friend T2* New(Args&&... args);
+ // So Delete() can call our private dtor.
+ template <typename T2>
+ friend void Delete(T2*);
+
SliceHashTable(size_t num_entries, Entry* entries, ValueCmp value_cmp);
virtual ~SliceHashTable();
diff --git a/src/core/lib/slice/slice_weak_hash_table.h b/src/core/lib/slice/slice_weak_hash_table.h
index 9d0ddfc..dc3ccc5 100644
--- a/src/core/lib/slice/slice_weak_hash_table.h
+++ b/src/core/lib/slice/slice_weak_hash_table.h
@@ -65,6 +65,10 @@
template <typename T2, typename... Args>
friend T2* New(Args&&... args);
+ // So Delete() can call our private dtor.
+ template <typename T2>
+ friend void Delete(T2*);
+
SliceWeakHashTable() = default;
~SliceWeakHashTable() = default;
diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc
index c683cc0..da48803 100644
--- a/src/core/lib/surface/call.cc
+++ b/src/core/lib/surface/call.cc
@@ -610,7 +610,7 @@
// This is called via the call combiner to start sending a batch down
// the filter stack.
static void execute_batch_in_call_combiner(void* arg, grpc_error* ignored) {
- GPR_TIMER_SCOPE("execute_batch", 0);
+ GPR_TIMER_SCOPE("execute_batch_in_call_combiner", 0);
grpc_transport_stream_op_batch* batch =
static_cast<grpc_transport_stream_op_batch*>(arg);
grpc_call* call = static_cast<grpc_call*>(batch->handler_private.extra_arg);
@@ -747,10 +747,10 @@
status[i] = unpack_received_status(gpr_atm_acq_load(&call->status[i]));
}
if (grpc_call_error_trace.enabled()) {
- gpr_log(GPR_DEBUG, "get_final_status %s", call->is_client ? "CLI" : "SVR");
+ gpr_log(GPR_INFO, "get_final_status %s", call->is_client ? "CLI" : "SVR");
for (i = 0; i < STATUS_SOURCE_COUNT; i++) {
if (status[i].is_set) {
- gpr_log(GPR_DEBUG, " %d: %s", i, grpc_error_string(status[i].error));
+ gpr_log(GPR_INFO, " %d: %s", i, grpc_error_string(status[i].error));
}
}
}
@@ -878,8 +878,8 @@
} else {
char* accept_encoding_entry_str =
grpc_slice_to_c_string(accept_encoding_entry_slice);
- gpr_log(GPR_ERROR,
- "Invalid entry in accept encoding metadata: '%s'. Ignoring.",
+ gpr_log(GPR_DEBUG,
+ "Unknown entry in accept encoding metadata: '%s'. Ignoring.",
accept_encoding_entry_str);
gpr_free(accept_encoding_entry_str);
}
@@ -1539,7 +1539,7 @@
static grpc_call_error call_start_batch(grpc_call* call, const grpc_op* ops,
size_t nops, void* notify_tag,
int is_notify_tag_closure) {
- GPR_TIMER_SCOPE("grpc_call_start_batch", 0);
+ GPR_TIMER_SCOPE("call_start_batch", 0);
size_t i;
const grpc_op* op;
diff --git a/src/core/lib/surface/channel.cc b/src/core/lib/surface/channel.cc
index cecc15b..d740ebd 100644
--- a/src/core/lib/surface/channel.cc
+++ b/src/core/lib/surface/channel.cc
@@ -60,7 +60,6 @@
struct grpc_channel {
int is_client;
grpc_compression_options compression_options;
- grpc_mdelem default_authority;
gpr_atm call_size_estimate;
@@ -117,40 +116,8 @@
grpc_compression_options_init(&channel->compression_options);
for (size_t i = 0; i < args->num_args; i++) {
- if (0 == strcmp(args->args[i].key, GRPC_ARG_DEFAULT_AUTHORITY)) {
- if (args->args[i].type != GRPC_ARG_STRING) {
- gpr_log(GPR_ERROR, "%s ignored: it must be a string",
- GRPC_ARG_DEFAULT_AUTHORITY);
- } else {
- if (!GRPC_MDISNULL(channel->default_authority)) {
- /* setting this takes precedence over anything else */
- GRPC_MDELEM_UNREF(channel->default_authority);
- }
- channel->default_authority = grpc_mdelem_from_slices(
- GRPC_MDSTR_AUTHORITY,
- grpc_slice_intern(
- grpc_slice_from_static_string(args->args[i].value.string)));
- }
- } else if (0 ==
- strcmp(args->args[i].key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG)) {
- if (args->args[i].type != GRPC_ARG_STRING) {
- gpr_log(GPR_ERROR, "%s ignored: it must be a string",
- GRPC_SSL_TARGET_NAME_OVERRIDE_ARG);
- } else {
- if (!GRPC_MDISNULL(channel->default_authority)) {
- /* other ways of setting this (notably ssl) take precedence */
- gpr_log(GPR_ERROR,
- "%s ignored: default host already set some other way",
- GRPC_SSL_TARGET_NAME_OVERRIDE_ARG);
- } else {
- channel->default_authority = grpc_mdelem_from_slices(
- GRPC_MDSTR_AUTHORITY,
- grpc_slice_intern(
- grpc_slice_from_static_string(args->args[i].value.string)));
- }
- }
- } else if (0 == strcmp(args->args[i].key,
- GRPC_COMPRESSION_CHANNEL_DEFAULT_LEVEL)) {
+ if (0 ==
+ strcmp(args->args[i].key, GRPC_COMPRESSION_CHANNEL_DEFAULT_LEVEL)) {
channel->compression_options.default_level.is_set = true;
channel->compression_options.default_level.level =
static_cast<grpc_compression_level>(grpc_channel_arg_get_integer(
@@ -189,6 +156,37 @@
return channel;
}
+static grpc_core::UniquePtr<char> get_default_authority(
+ const grpc_channel_args* input_args) {
+ bool has_default_authority = false;
+ char* ssl_override = nullptr;
+ grpc_core::UniquePtr<char> default_authority;
+ const size_t num_args = input_args != nullptr ? input_args->num_args : 0;
+ for (size_t i = 0; i < num_args; ++i) {
+ if (0 == strcmp(input_args->args[i].key, GRPC_ARG_DEFAULT_AUTHORITY)) {
+ has_default_authority = true;
+ } else if (0 == strcmp(input_args->args[i].key,
+ GRPC_SSL_TARGET_NAME_OVERRIDE_ARG)) {
+ ssl_override = grpc_channel_arg_get_string(&input_args->args[i]);
+ }
+ }
+ if (!has_default_authority && ssl_override != nullptr) {
+ default_authority.reset(gpr_strdup(ssl_override));
+ }
+ return default_authority;
+}
+
+static grpc_channel_args* build_channel_args(
+ const grpc_channel_args* input_args, char* default_authority) {
+ grpc_arg new_args[1];
+ size_t num_new_args = 0;
+ if (default_authority != nullptr) {
+ new_args[num_new_args++] = grpc_channel_arg_string_create(
+ const_cast<char*>(GRPC_ARG_DEFAULT_AUTHORITY), default_authority);
+ }
+ return grpc_channel_args_copy_and_add(input_args, new_args, num_new_args);
+}
+
char* grpc_channel_get_trace(grpc_channel* channel) {
return channel->tracer->RenderTrace();
}
@@ -202,7 +200,12 @@
grpc_channel_stack_type channel_stack_type,
grpc_transport* optional_transport) {
grpc_channel_stack_builder* builder = grpc_channel_stack_builder_create();
- grpc_channel_stack_builder_set_channel_arguments(builder, input_args);
+ const grpc_core::UniquePtr<char> default_authority =
+ get_default_authority(input_args);
+ grpc_channel_args* args =
+ build_channel_args(input_args, default_authority.get());
+ grpc_channel_stack_builder_set_channel_arguments(builder, args);
+ grpc_channel_args_destroy(args);
grpc_channel_stack_builder_set_target(builder, target);
grpc_channel_stack_builder_set_transport(builder, optional_transport);
if (!grpc_channel_init_create_stack(builder, channel_stack_type)) {
@@ -274,8 +277,6 @@
send_metadata[num_metadata++] = path_mdelem;
if (!GRPC_MDISNULL(authority_mdelem)) {
send_metadata[num_metadata++] = authority_mdelem;
- } else if (!GRPC_MDISNULL(channel->default_authority)) {
- send_metadata[num_metadata++] = GRPC_MDELEM_REF(channel->default_authority);
}
grpc_call_create_args args;
@@ -406,7 +407,6 @@
gpr_free(rc);
}
channel->tracer.reset();
- GRPC_MDELEM_UNREF(channel->default_authority);
gpr_mu_destroy(&channel->registered_call_mu);
gpr_free(channel->target);
gpr_free(channel);
diff --git a/src/core/lib/surface/completion_queue.cc b/src/core/lib/surface/completion_queue.cc
index d036391..f751741 100644
--- a/src/core/lib/surface/completion_queue.cc
+++ b/src/core/lib/surface/completion_queue.cc
@@ -390,7 +390,6 @@
static grpc_cq_completion* cq_event_queue_pop(grpc_cq_event_queue* q) {
grpc_cq_completion* c = nullptr;
- grpc_core::ExecCtx exec_ctx;
if (gpr_spinlock_trylock(&q->queue_lock)) {
GRPC_STATS_INC_CQ_EV_QUEUE_TRYLOCK_SUCCESSES();
diff --git a/src/core/lib/surface/init.cc b/src/core/lib/surface/init.cc
index 52e0ee1..bd436d6 100644
--- a/src/core/lib/surface/init.cc
+++ b/src/core/lib/surface/init.cc
@@ -172,7 +172,6 @@
}
}
}
- grpc_security_shutdown();
grpc_iomgr_shutdown();
gpr_timers_global_destroy();
grpc_tracer_shutdown();
diff --git a/src/core/lib/surface/init.h b/src/core/lib/surface/init.h
index d8282b4..9353208 100644
--- a/src/core/lib/surface/init.h
+++ b/src/core/lib/surface/init.h
@@ -22,7 +22,6 @@
void grpc_register_security_filters(void);
void grpc_security_pre_init(void);
void grpc_security_init(void);
-void grpc_security_shutdown(void);
int grpc_is_initialized(void);
#endif /* GRPC_CORE_LIB_SURFACE_INIT_H */
diff --git a/src/core/lib/surface/init_secure.cc b/src/core/lib/surface/init_secure.cc
index 3e4f1a8..28c6f7b 100644
--- a/src/core/lib/surface/init_secure.cc
+++ b/src/core/lib/surface/init_secure.cc
@@ -67,17 +67,15 @@
}
void grpc_register_security_filters(void) {
- grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL, INT_MAX,
+ // Register the auth client with a priority < INT_MAX to allow the authority
+ // filter -on which the auth filter depends- to be higher on the channel
+ // stack.
+ grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL, INT_MAX - 1,
maybe_prepend_client_auth_filter, nullptr);
- grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL, INT_MAX,
+ grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL, INT_MAX - 1,
maybe_prepend_client_auth_filter, nullptr);
grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX,
maybe_prepend_server_auth_filter, nullptr);
}
-void grpc_security_init() {
- grpc_security_register_handshaker_factories();
- grpc_core::DefaultSslRootStore::Initialize();
-}
-
-void grpc_security_shutdown() { grpc_core::DefaultSslRootStore::Destroy(); }
+void grpc_security_init() { grpc_security_register_handshaker_factories(); }
diff --git a/src/core/lib/surface/init_unsecure.cc b/src/core/lib/surface/init_unsecure.cc
index 1c8d07b..2b3bc64 100644
--- a/src/core/lib/surface/init_unsecure.cc
+++ b/src/core/lib/surface/init_unsecure.cc
@@ -25,5 +25,3 @@
void grpc_register_security_filters(void) {}
void grpc_security_init(void) {}
-
-void grpc_security_shutdown(void) {}
diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc
index f7505c8..cb34def 100644
--- a/src/core/lib/surface/server.cc
+++ b/src/core/lib/surface/server.cc
@@ -1161,6 +1161,22 @@
gpr_mu_unlock(&server->mu_global);
}
+/*
+ - Kills all pending requests-for-incoming-RPC-calls (i.e the requests made via
+ grpc_server_request_call and grpc_server_request_registered call will now be
+ cancelled). See 'kill_pending_work_locked()'
+
+ - Shuts down the listeners (i.e the server will no longer listen on the port
+ for new incoming channels).
+
+ - Iterates through all channels on the server and sends shutdown msg (see
+ 'channel_broadcaster_shutdown()' for details) to the clients via the
+ transport layer. The transport layer then guarantees the following:
+ -- Sends shutdown to the client (for eg: HTTP2 transport sends GOAWAY)
+ -- If the server has outstanding calls that are in the process, the
+ connection is NOT closed until the server is done with all those calls
+ -- Once, there are no more calls in progress, the channel is closed
+ */
void grpc_server_shutdown_and_notify(grpc_server* server,
grpc_completion_queue* cq, void* tag) {
listener* l;
diff --git a/src/core/lib/surface/version.cc b/src/core/lib/surface/version.cc
index be196a7..306b7c3 100644
--- a/src/core/lib/surface/version.cc
+++ b/src/core/lib/surface/version.cc
@@ -25,4 +25,4 @@
const char* grpc_version_string(void) { return "6.0.0-dev"; }
-const char* grpc_g_stands_for(void) { return "gorgeous"; }
+const char* grpc_g_stands_for(void) { return "gloriosa"; }
diff --git a/src/core/lib/transport/bdp_estimator.cc b/src/core/lib/transport/bdp_estimator.cc
index 8130535..8e71f86 100644
--- a/src/core/lib/transport/bdp_estimator.cc
+++ b/src/core/lib/transport/bdp_estimator.cc
@@ -47,7 +47,7 @@
double bw = dt > 0 ? (static_cast<double>(accumulator_) / dt) : 0;
int start_inter_ping_delay = inter_ping_delay_;
if (grpc_bdp_estimator_trace.enabled()) {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"bdp[%s]:complete acc=%" PRId64 " est=%" PRId64
" dt=%lf bw=%lfMbs bw_est=%lfMbs",
name_, accumulator_, estimate_, dt, bw / 125000.0,
@@ -58,7 +58,7 @@
estimate_ = GPR_MAX(accumulator_, estimate_ * 2);
bw_est_ = bw;
if (grpc_bdp_estimator_trace.enabled()) {
- gpr_log(GPR_DEBUG, "bdp[%s]: estimate increased to %" PRId64, name_,
+ gpr_log(GPR_INFO, "bdp[%s]: estimate increased to %" PRId64, name_,
estimate_);
}
inter_ping_delay_ /= 2; // if the ping estimate changes,
@@ -75,7 +75,7 @@
if (start_inter_ping_delay != inter_ping_delay_) {
stable_estimate_count_ = 0;
if (grpc_bdp_estimator_trace.enabled()) {
- gpr_log(GPR_DEBUG, "bdp[%s]:update_inter_time to %dms", name_,
+ gpr_log(GPR_INFO, "bdp[%s]:update_inter_time to %dms", name_,
inter_ping_delay_);
}
}
diff --git a/src/core/lib/transport/bdp_estimator.h b/src/core/lib/transport/bdp_estimator.h
index e703af1..ab13ae4 100644
--- a/src/core/lib/transport/bdp_estimator.h
+++ b/src/core/lib/transport/bdp_estimator.h
@@ -50,7 +50,7 @@
// transport (but not necessarily started)
void SchedulePing() {
if (grpc_bdp_estimator_trace.enabled()) {
- gpr_log(GPR_DEBUG, "bdp[%s]:sched acc=%" PRId64 " est=%" PRId64, name_,
+ gpr_log(GPR_INFO, "bdp[%s]:sched acc=%" PRId64 " est=%" PRId64, name_,
accumulator_, estimate_);
}
GPR_ASSERT(ping_state_ == PingState::UNSCHEDULED);
@@ -63,7 +63,7 @@
// the ping is on the wire
void StartPing() {
if (grpc_bdp_estimator_trace.enabled()) {
- gpr_log(GPR_DEBUG, "bdp[%s]:start acc=%" PRId64 " est=%" PRId64, name_,
+ gpr_log(GPR_INFO, "bdp[%s]:start acc=%" PRId64 " est=%" PRId64, name_,
accumulator_, estimate_);
}
GPR_ASSERT(ping_state_ == PingState::SCHEDULED);
diff --git a/src/core/lib/transport/connectivity_state.cc b/src/core/lib/transport/connectivity_state.cc
index 0122e77..db6b6c0 100644
--- a/src/core/lib/transport/connectivity_state.cc
+++ b/src/core/lib/transport/connectivity_state.cc
@@ -78,7 +78,7 @@
grpc_connectivity_state cur = static_cast<grpc_connectivity_state>(
gpr_atm_no_barrier_load(&tracker->current_state_atm));
if (grpc_connectivity_state_trace.enabled()) {
- gpr_log(GPR_DEBUG, "CONWATCH: %p %s: get %s", tracker, tracker->name,
+ gpr_log(GPR_INFO, "CONWATCH: %p %s: get %s", tracker, tracker->name,
grpc_connectivity_state_name(cur));
}
return cur;
@@ -89,7 +89,7 @@
grpc_connectivity_state cur = static_cast<grpc_connectivity_state>(
gpr_atm_no_barrier_load(&tracker->current_state_atm));
if (grpc_connectivity_state_trace.enabled()) {
- gpr_log(GPR_DEBUG, "CONWATCH: %p %s: get %s", tracker, tracker->name,
+ gpr_log(GPR_INFO, "CONWATCH: %p %s: get %s", tracker, tracker->name,
grpc_connectivity_state_name(cur));
}
if (error != nullptr) {
@@ -110,10 +110,10 @@
gpr_atm_no_barrier_load(&tracker->current_state_atm));
if (grpc_connectivity_state_trace.enabled()) {
if (current == nullptr) {
- gpr_log(GPR_DEBUG, "CONWATCH: %p %s: unsubscribe notify=%p", tracker,
+ gpr_log(GPR_INFO, "CONWATCH: %p %s: unsubscribe notify=%p", tracker,
tracker->name, notify);
} else {
- gpr_log(GPR_DEBUG, "CONWATCH: %p %s: from %s [cur=%s] notify=%p", tracker,
+ gpr_log(GPR_INFO, "CONWATCH: %p %s: from %s [cur=%s] notify=%p", tracker,
tracker->name, grpc_connectivity_state_name(*current),
grpc_connectivity_state_name(cur), notify);
}
@@ -161,7 +161,7 @@
grpc_connectivity_state_watcher* w;
if (grpc_connectivity_state_trace.enabled()) {
const char* error_string = grpc_error_string(error);
- gpr_log(GPR_DEBUG, "SET: %p %s: %s --> %s [%s] error=%p %s", tracker,
+ gpr_log(GPR_INFO, "SET: %p %s: %s --> %s [%s] error=%p %s", tracker,
tracker->name, grpc_connectivity_state_name(cur),
grpc_connectivity_state_name(state), reason, error, error_string);
}
@@ -187,8 +187,7 @@
*w->current = state;
tracker->watchers = w->next;
if (grpc_connectivity_state_trace.enabled()) {
- gpr_log(GPR_DEBUG, "NOTIFY: %p %s: %p", tracker, tracker->name,
- w->notify);
+ gpr_log(GPR_INFO, "NOTIFY: %p %s: %p", tracker, tracker->name, w->notify);
}
GRPC_CLOSURE_SCHED(w->notify, GRPC_ERROR_REF(tracker->current_error));
gpr_free(w);
diff --git a/src/core/plugin_registry/grpc_cronet_plugin_registry.cc b/src/core/plugin_registry/grpc_cronet_plugin_registry.cc
index 84228cb..49b9c7d 100644
--- a/src/core/plugin_registry/grpc_cronet_plugin_registry.cc
+++ b/src/core/plugin_registry/grpc_cronet_plugin_registry.cc
@@ -20,50 +20,30 @@
#include <grpc/grpc.h>
-void grpc_deadline_filter_init(void);
-void grpc_deadline_filter_shutdown(void);
-void grpc_client_channel_init(void);
-void grpc_client_channel_shutdown(void);
-void grpc_lb_policy_pick_first_init(void);
-void grpc_lb_policy_pick_first_shutdown(void);
-void grpc_max_age_filter_init(void);
-void grpc_max_age_filter_shutdown(void);
-void grpc_message_size_filter_init(void);
-void grpc_message_size_filter_shutdown(void);
-void grpc_resolver_dns_native_init(void);
-void grpc_resolver_dns_native_shutdown(void);
-void grpc_resolver_sockaddr_init(void);
-void grpc_resolver_sockaddr_shutdown(void);
-void grpc_server_load_reporting_plugin_init(void);
-void grpc_server_load_reporting_plugin_shutdown(void);
void grpc_http_filters_init(void);
void grpc_http_filters_shutdown(void);
void grpc_chttp2_plugin_init(void);
void grpc_chttp2_plugin_shutdown(void);
+void grpc_deadline_filter_init(void);
+void grpc_deadline_filter_shutdown(void);
+void grpc_client_channel_init(void);
+void grpc_client_channel_shutdown(void);
void grpc_tsi_alts_init(void);
void grpc_tsi_alts_shutdown(void);
+void grpc_server_load_reporting_plugin_init(void);
+void grpc_server_load_reporting_plugin_shutdown(void);
void grpc_register_built_in_plugins(void) {
- grpc_register_plugin(grpc_deadline_filter_init,
- grpc_deadline_filter_shutdown);
- grpc_register_plugin(grpc_client_channel_init,
- grpc_client_channel_shutdown);
- grpc_register_plugin(grpc_lb_policy_pick_first_init,
- grpc_lb_policy_pick_first_shutdown);
- grpc_register_plugin(grpc_max_age_filter_init,
- grpc_max_age_filter_shutdown);
- grpc_register_plugin(grpc_message_size_filter_init,
- grpc_message_size_filter_shutdown);
- grpc_register_plugin(grpc_resolver_dns_native_init,
- grpc_resolver_dns_native_shutdown);
- grpc_register_plugin(grpc_resolver_sockaddr_init,
- grpc_resolver_sockaddr_shutdown);
- grpc_register_plugin(grpc_server_load_reporting_plugin_init,
- grpc_server_load_reporting_plugin_shutdown);
grpc_register_plugin(grpc_http_filters_init,
grpc_http_filters_shutdown);
grpc_register_plugin(grpc_chttp2_plugin_init,
grpc_chttp2_plugin_shutdown);
+ grpc_register_plugin(grpc_deadline_filter_init,
+ grpc_deadline_filter_shutdown);
+ grpc_register_plugin(grpc_client_channel_init,
+ grpc_client_channel_shutdown);
grpc_register_plugin(grpc_tsi_alts_init,
grpc_tsi_alts_shutdown);
+ grpc_register_plugin(grpc_server_load_reporting_plugin_init,
+ grpc_server_load_reporting_plugin_shutdown);
}
diff --git a/src/core/plugin_registry/grpc_plugin_registry.cc b/src/core/plugin_registry/grpc_plugin_registry.cc
index 6f11e6b..e371310 100644
--- a/src/core/plugin_registry/grpc_plugin_registry.cc
+++ b/src/core/plugin_registry/grpc_plugin_registry.cc
@@ -52,6 +52,8 @@
void grpc_max_age_filter_shutdown(void);
void grpc_message_size_filter_init(void);
void grpc_message_size_filter_shutdown(void);
+void grpc_client_authority_filter_init(void);
+void grpc_client_authority_filter_shutdown(void);
void grpc_workaround_cronet_compression_filter_init(void);
void grpc_workaround_cronet_compression_filter_shutdown(void);
@@ -88,6 +90,8 @@
grpc_max_age_filter_shutdown);
grpc_register_plugin(grpc_message_size_filter_init,
grpc_message_size_filter_shutdown);
+ grpc_register_plugin(grpc_client_authority_filter_init,
+ grpc_client_authority_filter_shutdown);
grpc_register_plugin(grpc_workaround_cronet_compression_filter_init,
grpc_workaround_cronet_compression_filter_shutdown);
}
diff --git a/src/core/plugin_registry/grpc_unsecure_plugin_registry.cc b/src/core/plugin_registry/grpc_unsecure_plugin_registry.cc
index b08c5ce..283db5b 100644
--- a/src/core/plugin_registry/grpc_unsecure_plugin_registry.cc
+++ b/src/core/plugin_registry/grpc_unsecure_plugin_registry.cc
@@ -50,6 +50,8 @@
void grpc_max_age_filter_shutdown(void);
void grpc_message_size_filter_init(void);
void grpc_message_size_filter_shutdown(void);
+void grpc_client_authority_filter_init(void);
+void grpc_client_authority_filter_shutdown(void);
void grpc_workaround_cronet_compression_filter_init(void);
void grpc_workaround_cronet_compression_filter_shutdown(void);
@@ -84,6 +86,8 @@
grpc_max_age_filter_shutdown);
grpc_register_plugin(grpc_message_size_filter_init,
grpc_message_size_filter_shutdown);
+ grpc_register_plugin(grpc_client_authority_filter_init,
+ grpc_client_authority_filter_shutdown);
grpc_register_plugin(grpc_workaround_cronet_compression_filter_init,
grpc_workaround_cronet_compression_filter_shutdown);
}
diff --git a/src/core/tsi/alts/handshaker/alts_handshaker_client.cc b/src/core/tsi/alts/handshaker/alts_handshaker_client.cc
index 40f30e4..b5268ad 100644
--- a/src/core/tsi/alts/handshaker/alts_handshaker_client.cc
+++ b/src/core/tsi/alts/handshaker/alts_handshaker_client.cc
@@ -118,8 +118,7 @@
static tsi_result handshaker_client_start_client(alts_handshaker_client* client,
alts_tsi_event* event) {
if (client == nullptr || event == nullptr) {
- gpr_log(GPR_ERROR,
- "Invalid arguments to alts_grpc_handshaker_client_start_client()");
+ gpr_log(GPR_ERROR, "Invalid arguments to handshaker_client_start_client()");
return TSI_INVALID_ARGUMENT;
}
grpc_byte_buffer* buffer = get_serialized_start_client(event);
@@ -167,8 +166,7 @@
alts_tsi_event* event,
grpc_slice* bytes_received) {
if (client == nullptr || event == nullptr || bytes_received == nullptr) {
- gpr_log(GPR_ERROR,
- "Invalid arguments to alts_grpc_handshaker_client_start_server()");
+ gpr_log(GPR_ERROR, "Invalid arguments to handshaker_client_start_server()");
return TSI_INVALID_ARGUMENT;
}
grpc_byte_buffer* buffer = get_serialized_start_server(event, bytes_received);
@@ -206,8 +204,7 @@
alts_tsi_event* event,
grpc_slice* bytes_received) {
if (client == nullptr || event == nullptr || bytes_received == nullptr) {
- gpr_log(GPR_ERROR,
- "Invalid arguments to alts_grpc_handshaker_client_next()");
+ gpr_log(GPR_ERROR, "Invalid arguments to handshaker_client_next()");
return TSI_INVALID_ARGUMENT;
}
grpc_byte_buffer* buffer = get_serialized_next(bytes_received);
@@ -223,6 +220,13 @@
return result;
}
+static void handshaker_client_shutdown(alts_handshaker_client* client) {
+ GPR_ASSERT(client != nullptr);
+ alts_grpc_handshaker_client* grpc_client =
+ reinterpret_cast<alts_grpc_handshaker_client*>(client);
+ GPR_ASSERT(grpc_call_cancel(grpc_client->call, nullptr) == GRPC_CALL_OK);
+}
+
static void handshaker_client_destruct(alts_handshaker_client* client) {
if (client == nullptr) {
return;
@@ -234,7 +238,8 @@
static const alts_handshaker_client_vtable vtable = {
handshaker_client_start_client, handshaker_client_start_server,
- handshaker_client_next, handshaker_client_destruct};
+ handshaker_client_next, handshaker_client_shutdown,
+ handshaker_client_destruct};
alts_handshaker_client* alts_grpc_handshaker_client_create(
grpc_channel* channel, grpc_completion_queue* queue,
@@ -306,6 +311,13 @@
return TSI_INVALID_ARGUMENT;
}
+void alts_handshaker_client_shutdown(alts_handshaker_client* client) {
+ if (client != nullptr && client->vtable != nullptr &&
+ client->vtable->shutdown != nullptr) {
+ client->vtable->shutdown(client);
+ }
+}
+
void alts_handshaker_client_destroy(alts_handshaker_client* client) {
if (client != nullptr) {
if (client->vtable != nullptr && client->vtable->destruct != nullptr) {
diff --git a/src/core/tsi/alts/handshaker/alts_handshaker_client.h b/src/core/tsi/alts/handshaker/alts_handshaker_client.h
index fb2d2cf..8dd8fe4 100644
--- a/src/core/tsi/alts/handshaker/alts_handshaker_client.h
+++ b/src/core/tsi/alts/handshaker/alts_handshaker_client.h
@@ -51,6 +51,7 @@
alts_tsi_event* event, grpc_slice* bytes_received);
tsi_result (*next)(alts_handshaker_client* client, alts_tsi_event* event,
grpc_slice* bytes_received);
+ void (*shutdown)(alts_handshaker_client* client);
void (*destruct)(alts_handshaker_client* client);
} alts_handshaker_client_vtable;
@@ -100,6 +101,15 @@
grpc_slice* bytes_received);
/**
+ * This method cancels previously scheduled, but yet executed handshaker
+ * requests to ALTS handshaker service. After this operation, the handshake
+ * will be shutdown, and no more handshaker requests will get scheduled.
+ *
+ * - client: ALTS handshaker client instance.
+ */
+void alts_handshaker_client_shutdown(alts_handshaker_client* client);
+
+/**
* This method destroys a ALTS handshaker client.
*
* - client: a ALTS handshaker client instance.
diff --git a/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc b/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc
index 529f210..9676085 100644
--- a/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc
+++ b/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc
@@ -241,6 +241,10 @@
gpr_log(GPR_ERROR, "Invalid arguments to handshaker_next()");
return TSI_INVALID_ARGUMENT;
}
+ if (self->handshake_shutdown) {
+ gpr_log(GPR_ERROR, "TSI handshake shutdown");
+ return TSI_HANDSHAKE_SHUTDOWN;
+ }
alts_tsi_handshaker* handshaker =
reinterpret_cast<alts_tsi_handshaker*>(self);
tsi_result ok = TSI_OK;
@@ -277,6 +281,16 @@
return TSI_ASYNC;
}
+static void handshaker_shutdown(tsi_handshaker* self) {
+ GPR_ASSERT(self != nullptr);
+ if (self->handshake_shutdown) {
+ return;
+ }
+ alts_tsi_handshaker* handshaker =
+ reinterpret_cast<alts_tsi_handshaker*>(self);
+ alts_handshaker_client_shutdown(handshaker->client);
+}
+
static void handshaker_destroy(tsi_handshaker* self) {
if (self == nullptr) {
return;
@@ -292,8 +306,10 @@
}
static const tsi_handshaker_vtable handshaker_vtable = {
- nullptr, nullptr, nullptr, nullptr, nullptr, handshaker_destroy,
- handshaker_next};
+ nullptr, nullptr,
+ nullptr, nullptr,
+ nullptr, handshaker_destroy,
+ handshaker_next, handshaker_shutdown};
static void thread_worker(void* arg) {
while (true) {
@@ -401,6 +417,11 @@
cb(TSI_INTERNAL_ERROR, user_data, nullptr, 0, nullptr);
return;
}
+ if (handshaker->base.handshake_shutdown) {
+ gpr_log(GPR_ERROR, "TSI handshake shutdown");
+ cb(TSI_HANDSHAKE_SHUTDOWN, user_data, nullptr, 0, nullptr);
+ return;
+ }
/* Failed grpc call check. */
if (!is_ok || status != GRPC_STATUS_OK) {
gpr_log(GPR_ERROR, "grpc call made to handshaker service failed");
@@ -479,5 +500,10 @@
handshaker->client = client;
}
+alts_handshaker_client* alts_tsi_handshaker_get_client_for_testing(
+ alts_tsi_handshaker* handshaker) {
+ return handshaker->client;
+}
+
} // namespace internal
} // namespace grpc_core
diff --git a/src/core/tsi/alts/handshaker/alts_tsi_handshaker_private.h b/src/core/tsi/alts/handshaker/alts_tsi_handshaker_private.h
index 9b7b9bb..9612071 100644
--- a/src/core/tsi/alts/handshaker/alts_tsi_handshaker_private.h
+++ b/src/core/tsi/alts/handshaker/alts_tsi_handshaker_private.h
@@ -33,6 +33,9 @@
void alts_tsi_handshaker_set_client_for_testing(alts_tsi_handshaker* handshaker,
alts_handshaker_client* client);
+alts_handshaker_client* alts_tsi_handshaker_get_client_for_testing(
+ alts_tsi_handshaker* handshaker);
+
/* For testing only. */
bool alts_tsi_handshaker_get_has_sent_start_message_for_testing(
alts_tsi_handshaker* handshaker);
diff --git a/src/core/tsi/fake_transport_security.cc b/src/core/tsi/fake_transport_security.cc
index ad08b50..4d4c495 100644
--- a/src/core/tsi/fake_transport_security.cc
+++ b/src/core/tsi/fake_transport_security.cc
@@ -738,6 +738,7 @@
nullptr, /* create_frame_protector -- deprecated */
fake_handshaker_destroy,
fake_handshaker_next,
+ nullptr, /* shutdown */
};
tsi_handshaker* tsi_create_fake_handshaker(int is_client) {
diff --git a/src/core/tsi/ssl/session_cache/ssl_session_cache.h b/src/core/tsi/ssl/session_cache/ssl_session_cache.h
index 488638c..a90cca1 100644
--- a/src/core/tsi/ssl/session_cache/ssl_session_cache.h
+++ b/src/core/tsi/ssl/session_cache/ssl_session_cache.h
@@ -69,6 +69,10 @@
template <typename T, typename... Args>
friend T* grpc_core::New(Args&&... args);
+ // So Delete() can call our private dtor.
+ template <typename T>
+ friend void grpc_core::Delete(T*);
+
class Node;
explicit SslSessionLRUCache(size_t capacity);
diff --git a/src/core/tsi/ssl_transport_security.cc b/src/core/tsi/ssl_transport_security.cc
index 0ba6587..8065a8b 100644
--- a/src/core/tsi/ssl_transport_security.cc
+++ b/src/core/tsi/ssl_transport_security.cc
@@ -57,6 +57,7 @@
#define TSI_SSL_MAX_PROTECTED_FRAME_SIZE_UPPER_BOUND 16384
#define TSI_SSL_MAX_PROTECTED_FRAME_SIZE_LOWER_BOUND 1024
+#define TSI_SSL_HANDSHAKER_OUTGOING_BUFFER_INITIAL_SIZE 1024
/* Putting a macro like this and littering the source file with #if is really
bad practice.
@@ -105,10 +106,20 @@
SSL* ssl;
BIO* network_io;
tsi_result result;
+ unsigned char* outgoing_bytes_buffer;
+ size_t outgoing_bytes_buffer_size;
tsi_ssl_handshaker_factory* factory_ref;
} tsi_ssl_handshaker;
typedef struct {
+ tsi_handshaker_result base;
+ SSL* ssl;
+ BIO* network_io;
+ unsigned char* unused_bytes;
+ size_t unused_bytes_size;
+} tsi_ssl_handshaker_result;
+
+typedef struct {
tsi_frame_protector base;
SSL* ssl;
BIO* network_io;
@@ -120,12 +131,14 @@
/* --- Library Initialization. ---*/
static gpr_once g_init_openssl_once = GPR_ONCE_INIT;
-static gpr_mu* g_openssl_mutexes = nullptr;
static int g_ssl_ctx_ex_factory_index = -1;
+static const unsigned char kSslSessionIdContext[] = {'g', 'r', 'p', 'c'};
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000
+static gpr_mu* g_openssl_mutexes = nullptr;
static void openssl_locking_cb(int mode, int type, const char* file,
int line) GRPC_UNUSED;
static unsigned long openssl_thread_id_cb(void) GRPC_UNUSED;
-static const unsigned char kSslSessionIdContext[] = {'g', 'r', 'p', 'c'};
static void openssl_locking_cb(int mode, int type, const char* file, int line) {
if (mode & CRYPTO_LOCK) {
@@ -138,22 +151,27 @@
static unsigned long openssl_thread_id_cb(void) {
return static_cast<unsigned long>(gpr_thd_currentid());
}
+#endif
static void init_openssl(void) {
- int i;
- int num_locks;
SSL_library_init();
SSL_load_error_strings();
OpenSSL_add_all_algorithms();
- num_locks = CRYPTO_num_locks();
- GPR_ASSERT(num_locks > 0);
- g_openssl_mutexes = static_cast<gpr_mu*>(
- gpr_malloc(static_cast<size_t>(num_locks) * sizeof(gpr_mu)));
- for (i = 0; i < CRYPTO_num_locks(); i++) {
- gpr_mu_init(&g_openssl_mutexes[i]);
+#if OPENSSL_VERSION_NUMBER < 0x10100000
+ if (!CRYPTO_get_locking_callback()) {
+ int num_locks = CRYPTO_num_locks();
+ GPR_ASSERT(num_locks > 0);
+ g_openssl_mutexes = static_cast<gpr_mu*>(
+ gpr_malloc(static_cast<size_t>(num_locks) * sizeof(gpr_mu)));
+ for (int i = 0; i < num_locks; i++) {
+ gpr_mu_init(&g_openssl_mutexes[i]);
+ }
+ CRYPTO_set_locking_callback(openssl_locking_cb);
+ CRYPTO_set_id_callback(openssl_thread_id_cb);
+ } else {
+ gpr_log(GPR_INFO, "OpenSSL callback has already been set.");
}
- CRYPTO_set_locking_callback(openssl_locking_cb);
- CRYPTO_set_id_callback(openssl_thread_id_cb);
+#endif
g_ssl_ctx_ex_factory_index =
SSL_CTX_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr);
GPR_ASSERT(g_ssl_ctx_ex_factory_index != -1);
@@ -987,94 +1005,15 @@
gpr_ref_init(&factory->refcount, 1);
}
-/* --- tsi_handshaker methods implementation. ---*/
+/* --- tsi_handshaker_result methods implementation. ---*/
-static tsi_result ssl_handshaker_get_bytes_to_send_to_peer(tsi_handshaker* self,
- unsigned char* bytes,
- size_t* bytes_size) {
- tsi_ssl_handshaker* impl = reinterpret_cast<tsi_ssl_handshaker*>(self);
- int bytes_read_from_ssl = 0;
- if (bytes == nullptr || bytes_size == nullptr || *bytes_size == 0 ||
- *bytes_size > INT_MAX) {
- return TSI_INVALID_ARGUMENT;
- }
- GPR_ASSERT(*bytes_size <= INT_MAX);
- bytes_read_from_ssl =
- BIO_read(impl->network_io, bytes, static_cast<int>(*bytes_size));
- if (bytes_read_from_ssl < 0) {
- *bytes_size = 0;
- if (!BIO_should_retry(impl->network_io)) {
- impl->result = TSI_INTERNAL_ERROR;
- return impl->result;
- } else {
- return TSI_OK;
- }
- }
- *bytes_size = static_cast<size_t>(bytes_read_from_ssl);
- return BIO_pending(impl->network_io) == 0 ? TSI_OK : TSI_INCOMPLETE_DATA;
-}
-
-static tsi_result ssl_handshaker_get_result(tsi_handshaker* self) {
- tsi_ssl_handshaker* impl = reinterpret_cast<tsi_ssl_handshaker*>(self);
- if ((impl->result == TSI_HANDSHAKE_IN_PROGRESS) &&
- SSL_is_init_finished(impl->ssl)) {
- impl->result = TSI_OK;
- }
- return impl->result;
-}
-
-static tsi_result ssl_handshaker_process_bytes_from_peer(
- tsi_handshaker* self, const unsigned char* bytes, size_t* bytes_size) {
- tsi_ssl_handshaker* impl = reinterpret_cast<tsi_ssl_handshaker*>(self);
- int bytes_written_into_ssl_size = 0;
- if (bytes == nullptr || bytes_size == nullptr || *bytes_size > INT_MAX) {
- return TSI_INVALID_ARGUMENT;
- }
- GPR_ASSERT(*bytes_size <= INT_MAX);
- bytes_written_into_ssl_size =
- BIO_write(impl->network_io, bytes, static_cast<int>(*bytes_size));
- if (bytes_written_into_ssl_size < 0) {
- gpr_log(GPR_ERROR, "Could not write to memory BIO.");
- impl->result = TSI_INTERNAL_ERROR;
- return impl->result;
- }
- *bytes_size = static_cast<size_t>(bytes_written_into_ssl_size);
-
- if (!tsi_handshaker_is_in_progress(self)) {
- impl->result = TSI_OK;
- return impl->result;
- } else {
- /* Get ready to get some bytes from SSL. */
- int ssl_result = SSL_do_handshake(impl->ssl);
- ssl_result = SSL_get_error(impl->ssl, ssl_result);
- switch (ssl_result) {
- case SSL_ERROR_WANT_READ:
- if (BIO_pending(impl->network_io) == 0) {
- /* We need more data. */
- return TSI_INCOMPLETE_DATA;
- } else {
- return TSI_OK;
- }
- case SSL_ERROR_NONE:
- return TSI_OK;
- default: {
- char err_str[256];
- ERR_error_string_n(ERR_get_error(), err_str, sizeof(err_str));
- gpr_log(GPR_ERROR, "Handshake failed with fatal error %s: %s.",
- ssl_error_string(ssl_result), err_str);
- impl->result = TSI_PROTOCOL_FAILURE;
- return impl->result;
- }
- }
- }
-}
-
-static tsi_result ssl_handshaker_extract_peer(tsi_handshaker* self,
- tsi_peer* peer) {
+static tsi_result ssl_handshaker_result_extract_peer(
+ const tsi_handshaker_result* self, tsi_peer* peer) {
tsi_result result = TSI_OK;
const unsigned char* alpn_selected = nullptr;
unsigned int alpn_selected_len;
- tsi_ssl_handshaker* impl = reinterpret_cast<tsi_ssl_handshaker*>(self);
+ const tsi_ssl_handshaker_result* impl =
+ reinterpret_cast<const tsi_ssl_handshaker_result*>(self);
X509* peer_cert = SSL_get_peer_certificate(impl->ssl);
if (peer_cert != nullptr) {
result = peer_from_x509(peer_cert, 1, peer);
@@ -1120,12 +1059,14 @@
return result;
}
-static tsi_result ssl_handshaker_create_frame_protector(
- tsi_handshaker* self, size_t* max_output_protected_frame_size,
+static tsi_result ssl_handshaker_result_create_frame_protector(
+ const tsi_handshaker_result* self, size_t* max_output_protected_frame_size,
tsi_frame_protector** protector) {
size_t actual_max_output_protected_frame_size =
TSI_SSL_MAX_PROTECTED_FRAME_SIZE_UPPER_BOUND;
- tsi_ssl_handshaker* impl = reinterpret_cast<tsi_ssl_handshaker*>(self);
+ tsi_ssl_handshaker_result* impl =
+ reinterpret_cast<tsi_ssl_handshaker_result*>(
+ const_cast<tsi_handshaker_result*>(self));
tsi_ssl_frame_protector* protector_impl =
static_cast<tsi_ssl_frame_protector*>(
gpr_zalloc(sizeof(*protector_impl)));
@@ -1153,35 +1094,218 @@
return TSI_INTERNAL_ERROR;
}
- /* Transfer ownership of ssl and network_io to the frame protector. It is OK
- * as the caller cannot call anything else but destroy on the handshaker
- * after this call. */
+ /* Transfer ownership of ssl and network_io to the frame protector. */
protector_impl->ssl = impl->ssl;
impl->ssl = nullptr;
protector_impl->network_io = impl->network_io;
impl->network_io = nullptr;
-
protector_impl->base.vtable = &frame_protector_vtable;
*protector = &protector_impl->base;
return TSI_OK;
}
+static tsi_result ssl_handshaker_result_get_unused_bytes(
+ const tsi_handshaker_result* self, const unsigned char** bytes,
+ size_t* bytes_size) {
+ const tsi_ssl_handshaker_result* impl =
+ reinterpret_cast<const tsi_ssl_handshaker_result*>(self);
+ *bytes_size = impl->unused_bytes_size;
+ *bytes = impl->unused_bytes;
+ return TSI_OK;
+}
+
+static void ssl_handshaker_result_destroy(tsi_handshaker_result* self) {
+ tsi_ssl_handshaker_result* impl =
+ reinterpret_cast<tsi_ssl_handshaker_result*>(self);
+ SSL_free(impl->ssl);
+ BIO_free(impl->network_io);
+ gpr_free(impl->unused_bytes);
+ gpr_free(impl);
+}
+
+static const tsi_handshaker_result_vtable handshaker_result_vtable = {
+ ssl_handshaker_result_extract_peer,
+ nullptr, /* create_zero_copy_grpc_protector */
+ ssl_handshaker_result_create_frame_protector,
+ ssl_handshaker_result_get_unused_bytes,
+ ssl_handshaker_result_destroy,
+};
+
+static tsi_result ssl_handshaker_result_create(
+ tsi_ssl_handshaker* handshaker, const unsigned char* unused_bytes,
+ size_t unused_bytes_size, tsi_handshaker_result** handshaker_result) {
+ if (handshaker == nullptr || handshaker_result == nullptr ||
+ (unused_bytes_size > 0 && unused_bytes == nullptr)) {
+ return TSI_INVALID_ARGUMENT;
+ }
+ tsi_ssl_handshaker_result* result =
+ static_cast<tsi_ssl_handshaker_result*>(gpr_zalloc(sizeof(*result)));
+ result->base.vtable = &handshaker_result_vtable;
+ /* Transfer ownership of ssl and network_io to the handshaker result. */
+ result->ssl = handshaker->ssl;
+ handshaker->ssl = nullptr;
+ result->network_io = handshaker->network_io;
+ handshaker->network_io = nullptr;
+ if (unused_bytes_size > 0) {
+ result->unused_bytes =
+ static_cast<unsigned char*>(gpr_malloc(unused_bytes_size));
+ memcpy(result->unused_bytes, unused_bytes, unused_bytes_size);
+ }
+ result->unused_bytes_size = unused_bytes_size;
+ *handshaker_result = &result->base;
+ return TSI_OK;
+}
+
+/* --- tsi_handshaker methods implementation. ---*/
+
+static tsi_result ssl_handshaker_get_bytes_to_send_to_peer(
+ tsi_ssl_handshaker* impl, unsigned char* bytes, size_t* bytes_size) {
+ int bytes_read_from_ssl = 0;
+ if (bytes == nullptr || bytes_size == nullptr || *bytes_size == 0 ||
+ *bytes_size > INT_MAX) {
+ return TSI_INVALID_ARGUMENT;
+ }
+ GPR_ASSERT(*bytes_size <= INT_MAX);
+ bytes_read_from_ssl =
+ BIO_read(impl->network_io, bytes, static_cast<int>(*bytes_size));
+ if (bytes_read_from_ssl < 0) {
+ *bytes_size = 0;
+ if (!BIO_should_retry(impl->network_io)) {
+ impl->result = TSI_INTERNAL_ERROR;
+ return impl->result;
+ } else {
+ return TSI_OK;
+ }
+ }
+ *bytes_size = static_cast<size_t>(bytes_read_from_ssl);
+ return BIO_pending(impl->network_io) == 0 ? TSI_OK : TSI_INCOMPLETE_DATA;
+}
+
+static tsi_result ssl_handshaker_get_result(tsi_ssl_handshaker* impl) {
+ if ((impl->result == TSI_HANDSHAKE_IN_PROGRESS) &&
+ SSL_is_init_finished(impl->ssl)) {
+ impl->result = TSI_OK;
+ }
+ return impl->result;
+}
+
+static tsi_result ssl_handshaker_process_bytes_from_peer(
+ tsi_ssl_handshaker* impl, const unsigned char* bytes, size_t* bytes_size) {
+ int bytes_written_into_ssl_size = 0;
+ if (bytes == nullptr || bytes_size == nullptr || *bytes_size > INT_MAX) {
+ return TSI_INVALID_ARGUMENT;
+ }
+ GPR_ASSERT(*bytes_size <= INT_MAX);
+ bytes_written_into_ssl_size =
+ BIO_write(impl->network_io, bytes, static_cast<int>(*bytes_size));
+ if (bytes_written_into_ssl_size < 0) {
+ gpr_log(GPR_ERROR, "Could not write to memory BIO.");
+ impl->result = TSI_INTERNAL_ERROR;
+ return impl->result;
+ }
+ *bytes_size = static_cast<size_t>(bytes_written_into_ssl_size);
+
+ if (ssl_handshaker_get_result(impl) != TSI_HANDSHAKE_IN_PROGRESS) {
+ impl->result = TSI_OK;
+ return impl->result;
+ } else {
+ /* Get ready to get some bytes from SSL. */
+ int ssl_result = SSL_do_handshake(impl->ssl);
+ ssl_result = SSL_get_error(impl->ssl, ssl_result);
+ switch (ssl_result) {
+ case SSL_ERROR_WANT_READ:
+ if (BIO_pending(impl->network_io) == 0) {
+ /* We need more data. */
+ return TSI_INCOMPLETE_DATA;
+ } else {
+ return TSI_OK;
+ }
+ case SSL_ERROR_NONE:
+ return TSI_OK;
+ default: {
+ char err_str[256];
+ ERR_error_string_n(ERR_get_error(), err_str, sizeof(err_str));
+ gpr_log(GPR_ERROR, "Handshake failed with fatal error %s: %s.",
+ ssl_error_string(ssl_result), err_str);
+ impl->result = TSI_PROTOCOL_FAILURE;
+ return impl->result;
+ }
+ }
+ }
+}
+
static void ssl_handshaker_destroy(tsi_handshaker* self) {
tsi_ssl_handshaker* impl = reinterpret_cast<tsi_ssl_handshaker*>(self);
SSL_free(impl->ssl);
BIO_free(impl->network_io);
+ gpr_free(impl->outgoing_bytes_buffer);
tsi_ssl_handshaker_factory_unref(impl->factory_ref);
gpr_free(impl);
}
+static tsi_result ssl_handshaker_next(
+ tsi_handshaker* self, const unsigned char* received_bytes,
+ size_t received_bytes_size, const unsigned char** bytes_to_send,
+ size_t* bytes_to_send_size, tsi_handshaker_result** handshaker_result,
+ tsi_handshaker_on_next_done_cb cb, void* user_data) {
+ /* Input sanity check. */
+ if ((received_bytes_size > 0 && received_bytes == nullptr) ||
+ bytes_to_send == nullptr || bytes_to_send_size == nullptr ||
+ handshaker_result == nullptr) {
+ return TSI_INVALID_ARGUMENT;
+ }
+ /* If there are received bytes, process them first. */
+ tsi_ssl_handshaker* impl = reinterpret_cast<tsi_ssl_handshaker*>(self);
+ tsi_result status = TSI_OK;
+ size_t bytes_consumed = received_bytes_size;
+ if (received_bytes_size > 0) {
+ status = ssl_handshaker_process_bytes_from_peer(impl, received_bytes,
+ &bytes_consumed);
+ if (status != TSI_OK) return status;
+ }
+ /* Get bytes to send to the peer, if available. */
+ size_t offset = 0;
+ do {
+ size_t to_send_size = impl->outgoing_bytes_buffer_size - offset;
+ status = ssl_handshaker_get_bytes_to_send_to_peer(
+ impl, impl->outgoing_bytes_buffer + offset, &to_send_size);
+ offset += to_send_size;
+ if (status == TSI_INCOMPLETE_DATA) {
+ impl->outgoing_bytes_buffer_size *= 2;
+ impl->outgoing_bytes_buffer = static_cast<unsigned char*>(gpr_realloc(
+ impl->outgoing_bytes_buffer, impl->outgoing_bytes_buffer_size));
+ }
+ } while (status == TSI_INCOMPLETE_DATA);
+ if (status != TSI_OK) return status;
+ *bytes_to_send = impl->outgoing_bytes_buffer;
+ *bytes_to_send_size = offset;
+ /* If handshake completes, create tsi_handshaker_result. */
+ if (ssl_handshaker_get_result(impl) == TSI_HANDSHAKE_IN_PROGRESS) {
+ *handshaker_result = nullptr;
+ } else {
+ size_t unused_bytes_size = received_bytes_size - bytes_consumed;
+ const unsigned char* unused_bytes =
+ unused_bytes_size == 0 ? nullptr : received_bytes + bytes_consumed;
+ status = ssl_handshaker_result_create(impl, unused_bytes, unused_bytes_size,
+ handshaker_result);
+ if (status == TSI_OK) {
+ /* Indicates that the handshake has completed and that a handshaker_result
+ * has been created. */
+ self->handshaker_result_created = true;
+ }
+ }
+ return status;
+}
+
static const tsi_handshaker_vtable handshaker_vtable = {
- ssl_handshaker_get_bytes_to_send_to_peer,
- ssl_handshaker_process_bytes_from_peer,
- ssl_handshaker_get_result,
- ssl_handshaker_extract_peer,
- ssl_handshaker_create_frame_protector,
+ nullptr, /* get_bytes_to_send_to_peer -- deprecated */
+ nullptr, /* process_bytes_from_peer -- deprecated */
+ nullptr, /* get_result -- deprecated */
+ nullptr, /* extract_peer -- deprecated */
+ nullptr, /* create_frame_protector -- deprecated */
ssl_handshaker_destroy,
- nullptr,
+ ssl_handshaker_next,
+ nullptr, /* shutdown */
};
/* --- tsi_ssl_handshaker_factory common methods. --- */
@@ -1259,6 +1383,10 @@
impl->ssl = ssl;
impl->network_io = network_io;
impl->result = TSI_HANDSHAKE_IN_PROGRESS;
+ impl->outgoing_bytes_buffer_size =
+ TSI_SSL_HANDSHAKER_OUTGOING_BUFFER_INITIAL_SIZE;
+ impl->outgoing_bytes_buffer =
+ static_cast<unsigned char*>(gpr_zalloc(impl->outgoing_bytes_buffer_size));
impl->base.vtable = &handshaker_vtable;
impl->factory_ref = tsi_ssl_handshaker_factory_ref(factory);
diff --git a/src/core/tsi/transport_security.cc b/src/core/tsi/transport_security.cc
index 129533f..99b3229 100644
--- a/src/core/tsi/transport_security.cc
+++ b/src/core/tsi/transport_security.cc
@@ -136,6 +136,7 @@
return TSI_INVALID_ARGUMENT;
}
if (self->frame_protector_created) return TSI_FAILED_PRECONDITION;
+ if (self->handshake_shutdown) return TSI_HANDSHAKE_SHUTDOWN;
if (self->vtable->get_bytes_to_send_to_peer == nullptr)
return TSI_UNIMPLEMENTED;
return self->vtable->get_bytes_to_send_to_peer(self, bytes, bytes_size);
@@ -149,6 +150,7 @@
return TSI_INVALID_ARGUMENT;
}
if (self->frame_protector_created) return TSI_FAILED_PRECONDITION;
+ if (self->handshake_shutdown) return TSI_HANDSHAKE_SHUTDOWN;
if (self->vtable->process_bytes_from_peer == nullptr)
return TSI_UNIMPLEMENTED;
return self->vtable->process_bytes_from_peer(self, bytes, bytes_size);
@@ -157,6 +159,7 @@
tsi_result tsi_handshaker_get_result(tsi_handshaker* self) {
if (self == nullptr || self->vtable == nullptr) return TSI_INVALID_ARGUMENT;
if (self->frame_protector_created) return TSI_FAILED_PRECONDITION;
+ if (self->handshake_shutdown) return TSI_HANDSHAKE_SHUTDOWN;
if (self->vtable->get_result == nullptr) return TSI_UNIMPLEMENTED;
return self->vtable->get_result(self);
}
@@ -167,6 +170,7 @@
}
memset(peer, 0, sizeof(tsi_peer));
if (self->frame_protector_created) return TSI_FAILED_PRECONDITION;
+ if (self->handshake_shutdown) return TSI_HANDSHAKE_SHUTDOWN;
if (tsi_handshaker_get_result(self) != TSI_OK) {
return TSI_FAILED_PRECONDITION;
}
@@ -182,6 +186,7 @@
return TSI_INVALID_ARGUMENT;
}
if (self->frame_protector_created) return TSI_FAILED_PRECONDITION;
+ if (self->handshake_shutdown) return TSI_HANDSHAKE_SHUTDOWN;
if (tsi_handshaker_get_result(self) != TSI_OK) return TSI_FAILED_PRECONDITION;
if (self->vtable->create_frame_protector == nullptr) return TSI_UNIMPLEMENTED;
result = self->vtable->create_frame_protector(self, max_protected_frame_size,
@@ -199,12 +204,21 @@
tsi_handshaker_on_next_done_cb cb, void* user_data) {
if (self == nullptr || self->vtable == nullptr) return TSI_INVALID_ARGUMENT;
if (self->handshaker_result_created) return TSI_FAILED_PRECONDITION;
+ if (self->handshake_shutdown) return TSI_HANDSHAKE_SHUTDOWN;
if (self->vtable->next == nullptr) return TSI_UNIMPLEMENTED;
return self->vtable->next(self, received_bytes, received_bytes_size,
bytes_to_send, bytes_to_send_size,
handshaker_result, cb, user_data);
}
+void tsi_handshaker_shutdown(tsi_handshaker* self) {
+ if (self == nullptr || self->vtable == nullptr) return;
+ self->handshake_shutdown = true;
+ if (self->vtable->shutdown != nullptr) {
+ self->vtable->shutdown(self);
+ }
+}
+
void tsi_handshaker_destroy(tsi_handshaker* self) {
if (self == nullptr) return;
self->vtable->destroy(self);
diff --git a/src/core/tsi/transport_security.h b/src/core/tsi/transport_security.h
index b1ec82d..1923a70 100644
--- a/src/core/tsi/transport_security.h
+++ b/src/core/tsi/transport_security.h
@@ -73,12 +73,14 @@
size_t* bytes_to_send_size,
tsi_handshaker_result** handshaker_result,
tsi_handshaker_on_next_done_cb cb, void* user_data);
+ void (*shutdown)(tsi_handshaker* self);
} tsi_handshaker_vtable;
struct tsi_handshaker {
const tsi_handshaker_vtable* vtable;
bool frame_protector_created;
bool handshaker_result_created;
+ bool handshake_shutdown;
};
/* Base for tsi_handshaker_result implementations.
diff --git a/src/core/tsi/transport_security_adapter.cc b/src/core/tsi/transport_security_adapter.cc
deleted file mode 100644
index 25608f0..0000000
--- a/src/core/tsi/transport_security_adapter.cc
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- *
- * 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.
- *
- */
-
-#include <grpc/support/port_platform.h>
-
-#include "src/core/tsi/transport_security_adapter.h"
-
-#include <string.h>
-
-#include <grpc/support/alloc.h>
-#include <grpc/support/log.h>
-#include "src/core/tsi/transport_security.h"
-
-#define TSI_ADAPTER_INITIAL_BUFFER_SIZE 256
-
-/* --- tsi_adapter_handshaker_result implementation ---*/
-
-typedef struct {
- tsi_handshaker_result base;
- tsi_handshaker* wrapped;
- unsigned char* unused_bytes;
- size_t unused_bytes_size;
-} tsi_adapter_handshaker_result;
-
-static tsi_result adapter_result_extract_peer(const tsi_handshaker_result* self,
- tsi_peer* peer) {
- tsi_adapter_handshaker_result* impl = (tsi_adapter_handshaker_result*)self;
- return tsi_handshaker_extract_peer(impl->wrapped, peer);
-}
-
-static tsi_result adapter_result_create_frame_protector(
- const tsi_handshaker_result* self, size_t* max_output_protected_frame_size,
- tsi_frame_protector** protector) {
- tsi_adapter_handshaker_result* impl = (tsi_adapter_handshaker_result*)self;
- return tsi_handshaker_create_frame_protector(
- impl->wrapped, max_output_protected_frame_size, protector);
-}
-
-static tsi_result adapter_result_get_unused_bytes(
- const tsi_handshaker_result* self, const unsigned char** bytes,
- size_t* byte_size) {
- tsi_adapter_handshaker_result* impl = (tsi_adapter_handshaker_result*)self;
- *bytes = impl->unused_bytes;
- *byte_size = impl->unused_bytes_size;
- return TSI_OK;
-}
-
-static void adapter_result_destroy(tsi_handshaker_result* self) {
- tsi_adapter_handshaker_result* impl =
- reinterpret_cast<tsi_adapter_handshaker_result*>(self);
- tsi_handshaker_destroy(impl->wrapped);
- gpr_free(impl->unused_bytes);
- gpr_free(self);
-}
-
-static const tsi_handshaker_result_vtable result_vtable = {
- adapter_result_extract_peer,
- nullptr, /* create_zero_copy_grpc_protector */
- adapter_result_create_frame_protector,
- adapter_result_get_unused_bytes,
- adapter_result_destroy,
-};
-
-/* Ownership of wrapped tsi_handshaker is transferred to the result object. */
-static tsi_result tsi_adapter_create_handshaker_result(
- tsi_handshaker* wrapped, const unsigned char* unused_bytes,
- size_t unused_bytes_size, tsi_handshaker_result** handshaker_result) {
- if (wrapped == nullptr ||
- (unused_bytes_size > 0 && unused_bytes == nullptr)) {
- return TSI_INVALID_ARGUMENT;
- }
- tsi_adapter_handshaker_result* impl =
- static_cast<tsi_adapter_handshaker_result*>(gpr_zalloc(sizeof(*impl)));
- impl->base.vtable = &result_vtable;
- impl->wrapped = wrapped;
- impl->unused_bytes_size = unused_bytes_size;
- if (unused_bytes_size > 0) {
- impl->unused_bytes =
- static_cast<unsigned char*>(gpr_malloc(unused_bytes_size));
- memcpy(impl->unused_bytes, unused_bytes, unused_bytes_size);
- } else {
- impl->unused_bytes = nullptr;
- }
- *handshaker_result = &impl->base;
- return TSI_OK;
-}
-
-/* --- tsi_adapter_handshaker implementation ---*/
-
-typedef struct {
- tsi_handshaker base;
- tsi_handshaker* wrapped;
- unsigned char* adapter_buffer;
- size_t adapter_buffer_size;
-} tsi_adapter_handshaker;
-
-static tsi_result adapter_get_bytes_to_send_to_peer(tsi_handshaker* self,
- unsigned char* bytes,
- size_t* bytes_size) {
- return tsi_handshaker_get_bytes_to_send_to_peer(
- tsi_adapter_handshaker_get_wrapped(self), bytes, bytes_size);
-}
-
-static tsi_result adapter_process_bytes_from_peer(tsi_handshaker* self,
- const unsigned char* bytes,
- size_t* bytes_size) {
- return tsi_handshaker_process_bytes_from_peer(
- tsi_adapter_handshaker_get_wrapped(self), bytes, bytes_size);
-}
-
-static tsi_result adapter_get_result(tsi_handshaker* self) {
- return tsi_handshaker_get_result(tsi_adapter_handshaker_get_wrapped(self));
-}
-
-static tsi_result adapter_extract_peer(tsi_handshaker* self, tsi_peer* peer) {
- return tsi_handshaker_extract_peer(tsi_adapter_handshaker_get_wrapped(self),
- peer);
-}
-
-static tsi_result adapter_create_frame_protector(
- tsi_handshaker* self, size_t* max_protected_frame_size,
- tsi_frame_protector** protector) {
- return tsi_handshaker_create_frame_protector(
- tsi_adapter_handshaker_get_wrapped(self), max_protected_frame_size,
- protector);
-}
-
-static void adapter_destroy(tsi_handshaker* self) {
- tsi_adapter_handshaker* impl =
- reinterpret_cast<tsi_adapter_handshaker*>(self);
- tsi_handshaker_destroy(impl->wrapped);
- gpr_free(impl->adapter_buffer);
- gpr_free(self);
-}
-
-static tsi_result adapter_next(
- tsi_handshaker* self, const unsigned char* received_bytes,
- size_t received_bytes_size, const unsigned char** bytes_to_send,
- size_t* bytes_to_send_size, tsi_handshaker_result** handshaker_result,
- tsi_handshaker_on_next_done_cb cb, void* user_data) {
- /* Input sanity check. */
- if ((received_bytes_size > 0 && received_bytes == nullptr) ||
- bytes_to_send == nullptr || bytes_to_send_size == nullptr ||
- handshaker_result == nullptr) {
- return TSI_INVALID_ARGUMENT;
- }
-
- /* If there are received bytes, process them first. */
- tsi_adapter_handshaker* impl =
- reinterpret_cast<tsi_adapter_handshaker*>(self);
- tsi_result status = TSI_OK;
- size_t bytes_consumed = received_bytes_size;
- if (received_bytes_size > 0) {
- status = tsi_handshaker_process_bytes_from_peer(
- impl->wrapped, received_bytes, &bytes_consumed);
- if (status != TSI_OK) return status;
- }
-
- /* Get bytes to send to the peer, if available. */
- size_t offset = 0;
- do {
- size_t to_send_size = impl->adapter_buffer_size - offset;
- status = tsi_handshaker_get_bytes_to_send_to_peer(
- impl->wrapped, impl->adapter_buffer + offset, &to_send_size);
- offset += to_send_size;
- if (status == TSI_INCOMPLETE_DATA) {
- impl->adapter_buffer_size *= 2;
- impl->adapter_buffer = static_cast<unsigned char*>(
- gpr_realloc(impl->adapter_buffer, impl->adapter_buffer_size));
- }
- } while (status == TSI_INCOMPLETE_DATA);
- if (status != TSI_OK) return status;
- *bytes_to_send = impl->adapter_buffer;
- *bytes_to_send_size = offset;
-
- /* If handshake completes, create tsi_handshaker_result. */
- if (tsi_handshaker_is_in_progress(impl->wrapped)) {
- *handshaker_result = nullptr;
- } else {
- size_t unused_bytes_size = received_bytes_size - bytes_consumed;
- const unsigned char* unused_bytes =
- unused_bytes_size == 0 ? nullptr : received_bytes + bytes_consumed;
- status = tsi_adapter_create_handshaker_result(
- impl->wrapped, unused_bytes, unused_bytes_size, handshaker_result);
- if (status == TSI_OK) {
- impl->base.handshaker_result_created = true;
- impl->wrapped = nullptr;
- }
- }
- return status;
-}
-
-static const tsi_handshaker_vtable handshaker_vtable = {
- adapter_get_bytes_to_send_to_peer,
- adapter_process_bytes_from_peer,
- adapter_get_result,
- adapter_extract_peer,
- adapter_create_frame_protector,
- adapter_destroy,
- adapter_next,
-};
-
-tsi_handshaker* tsi_create_adapter_handshaker(tsi_handshaker* wrapped) {
- GPR_ASSERT(wrapped != nullptr);
- tsi_adapter_handshaker* impl =
- static_cast<tsi_adapter_handshaker*>(gpr_zalloc(sizeof(*impl)));
- impl->base.vtable = &handshaker_vtable;
- impl->wrapped = wrapped;
- impl->adapter_buffer_size = TSI_ADAPTER_INITIAL_BUFFER_SIZE;
- impl->adapter_buffer =
- static_cast<unsigned char*>(gpr_malloc(impl->adapter_buffer_size));
- return &impl->base;
-}
-
-tsi_handshaker* tsi_adapter_handshaker_get_wrapped(tsi_handshaker* adapter) {
- if (adapter == nullptr) return nullptr;
- tsi_adapter_handshaker* impl =
- reinterpret_cast<tsi_adapter_handshaker*>(adapter);
- return impl->wrapped;
-}
diff --git a/src/core/tsi/transport_security_adapter.h b/src/core/tsi/transport_security_adapter.h
deleted file mode 100644
index f83ecc5..0000000
--- a/src/core/tsi/transport_security_adapter.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- *
- * 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_TSI_TRANSPORT_SECURITY_ADAPTER_H
-#define GRPC_CORE_TSI_TRANSPORT_SECURITY_ADAPTER_H
-
-#include <grpc/support/port_platform.h>
-
-#include "src/core/tsi/transport_security_interface.h"
-
-/* Create a tsi handshaker that takes an implementation of old interface and
- converts into an implementation of new interface. In the old interface,
- there are get_bytes_to_send_to_peer, process_bytes_from_peer, get_result,
- extract_peer, and create_frame_protector. In the new interface, only next
- method is needed. See transport_security_interface.h for details. Note that
- this tsi adapter handshaker is temporary. It will be removed once TSI has
- been fully migrated to the new interface.
- Ownership of input tsi_handshaker is transferred to this new adapter. */
-tsi_handshaker* tsi_create_adapter_handshaker(tsi_handshaker* wrapped);
-
-/* Given a tsi adapter handshaker, return the original wrapped handshaker. The
- adapter still owns the wrapped handshaker which should not be destroyed by
- the caller. */
-tsi_handshaker* tsi_adapter_handshaker_get_wrapped(tsi_handshaker* adapter);
-
-#endif /* GRPC_CORE_TSI_TRANSPORT_SECURITY_ADAPTER_H */
diff --git a/src/core/tsi/transport_security_interface.h b/src/core/tsi/transport_security_interface.h
index 8c10866..7a0cdc3 100644
--- a/src/core/tsi/transport_security_interface.h
+++ b/src/core/tsi/transport_security_interface.h
@@ -42,7 +42,8 @@
TSI_PROTOCOL_FAILURE = 10,
TSI_HANDSHAKE_IN_PROGRESS = 11,
TSI_OUT_OF_RESOURCES = 12,
- TSI_ASYNC = 13
+ TSI_ASYNC = 13,
+ TSI_HANDSHAKE_SHUTDOWN = 14,
} tsi_result;
typedef enum {
@@ -332,6 +333,8 @@
------------------------------------------------------------------------ */
typedef struct tsi_handshaker tsi_handshaker;
+/* TODO(jiangtaoli2016): Cleans up deprecated methods when we are ready. */
+
/* TO BE DEPRECATED SOON. Use tsi_handshaker_next instead.
Gets bytes that need to be sent to the peer.
- bytes is the buffer that will be written with the data to be sent to the
@@ -440,6 +443,13 @@
size_t* bytes_to_send_size, tsi_handshaker_result** handshaker_result,
tsi_handshaker_on_next_done_cb cb, void* user_data);
+/* This method shuts down a TSI handshake that is in progress.
+ *
+ * This method will be invoked when TSI handshake should be terminated before
+ * being finished in order to free any resources being used.
+ */
+void tsi_handshaker_shutdown(tsi_handshaker* self);
+
/* This method releases the tsi_handshaker object. After this method is called,
no other method can be called on the object. */
void tsi_handshaker_destroy(tsi_handshaker* self);
diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc
index 19d67c2..00245b3 100644
--- a/src/cpp/client/secure_credentials.cc
+++ b/src/cpp/client/secure_credentials.cc
@@ -87,6 +87,27 @@
return WrapChannelCredentials(c_creds);
}
+namespace experimental {
+
+// Builds ALTS Credentials given ALTS specific options
+std::shared_ptr<ChannelCredentials> AltsCredentials(
+ const AltsCredentialsOptions& options) {
+ GrpcLibraryCodegen init; // To call grpc_init().
+ grpc_alts_credentials_options* c_options =
+ grpc_alts_credentials_client_options_create();
+ for (auto service_account = options.target_service_accounts.begin();
+ service_account != options.target_service_accounts.end();
+ service_account++) {
+ grpc_alts_credentials_client_options_add_target_service_account(
+ c_options, service_account->c_str());
+ }
+ grpc_channel_credentials* c_creds = grpc_alts_credentials_create(c_options);
+ grpc_alts_credentials_options_destroy(c_options);
+ return WrapChannelCredentials(c_creds);
+}
+
+} // namespace experimental
+
// Builds credentials for use when running in GCE
std::shared_ptr<CallCredentials> GoogleComputeEngineCredentials() {
GrpcLibraryCodegen init; // To call grpc_init().
diff --git a/src/cpp/common/core_codegen.cc b/src/cpp/common/core_codegen.cc
index aa9788d..619aaca 100644
--- a/src/cpp/common/core_codegen.cc
+++ b/src/cpp/common/core_codegen.cc
@@ -98,6 +98,10 @@
::grpc_byte_buffer_destroy(bb);
}
+size_t CoreCodegen::grpc_byte_buffer_length(grpc_byte_buffer* bb) {
+ return ::grpc_byte_buffer_length(bb);
+}
+
grpc_call_error CoreCodegen::grpc_call_cancel_with_status(
grpc_call* call, grpc_status_code status, const char* description,
void* reserved) {
@@ -135,6 +139,12 @@
return ::grpc_slice_new_with_user_data(p, len, destroy, user_data);
}
+grpc_slice CoreCodegen::grpc_slice_new_with_len(void* p, size_t len,
+ void (*destroy)(void*,
+ size_t)) {
+ return ::grpc_slice_new_with_len(p, len, destroy);
+}
+
grpc_slice CoreCodegen::grpc_empty_slice() { return ::grpc_empty_slice(); }
grpc_slice CoreCodegen::grpc_slice_malloc(size_t length) {
diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc
index fb1723c..54cd207 100644
--- a/src/cpp/common/version_cc.cc
+++ b/src/cpp/common/version_cc.cc
@@ -22,5 +22,5 @@
#include <grpcpp/grpcpp.h>
namespace grpc {
-grpc::string Version() { return "1.11.0-dev"; }
+grpc::string Version() { return "1.13.0-dev"; }
} // namespace grpc
diff --git a/src/cpp/server/load_reporter/load_data_store.cc b/src/cpp/server/load_reporter/load_data_store.cc
new file mode 100644
index 0000000..70f12c1
--- /dev/null
+++ b/src/cpp/server/load_reporter/load_data_store.cc
@@ -0,0 +1,273 @@
+/*
+ *
+ * Copyright 2018 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.
+ *
+ */
+
+#include <cstdlib>
+#include <set>
+#include <unordered_map>
+#include <vector>
+
+#include "src/cpp/server/load_reporter/load_data_store.h"
+
+namespace grpc {
+namespace load_reporter {
+
+// Some helper functions.
+namespace {
+
+// Given a map from type K to a set of value type V, finds the set associated
+// with the given key and erases the value from the set. If the set becomes
+// empty, also erases the key-set pair. Returns true if the value is erased
+// successfully.
+template <typename K, typename V>
+bool UnorderedMapOfSetEraseKeyValue(std::unordered_map<K, std::set<V>>& map,
+ const K& key, const V& value) {
+ auto it = map.find(key);
+ if (it != map.end()) {
+ size_t erased = it->second.erase(value);
+ if (it->second.size() == 0) {
+ map.erase(it);
+ }
+ return erased;
+ }
+ return false;
+};
+
+// Given a map from type K to a set of value type V, removes the given key and
+// the associated set, and returns the set. Returns an empty set if the key is
+// not found.
+template <typename K, typename V>
+std::set<V> UnorderedMapOfSetExtract(std::unordered_map<K, std::set<V>>& map,
+ const K& key) {
+ auto it = map.find(key);
+ if (it != map.end()) {
+ auto set = std::move(it->second);
+ map.erase(it);
+ return set;
+ }
+ return {};
+};
+
+// From a non-empty container, returns a pointer to a random element.
+template <typename C>
+const typename C::value_type* RandomElement(const C& container) {
+ GPR_ASSERT(!container.empty());
+ auto it = container.begin();
+ std::advance(it, std::rand() % container.size());
+ return &(*it);
+}
+
+} // namespace
+
+void PerBalancerStore::MergeRow(const LoadRecordKey& key,
+ const LoadRecordValue& value) {
+ // During suspension, the load data received will be dropped.
+ if (!suspended_) {
+ load_record_map_[key].MergeFrom(value);
+ gpr_log(GPR_DEBUG,
+ "[PerBalancerStore %p] Load data merged (Key: %s, Value: %s).",
+ this, key.ToString().c_str(), value.ToString().c_str());
+ } else {
+ gpr_log(GPR_DEBUG,
+ "[PerBalancerStore %p] Load data dropped (Key: %s, Value: %s).",
+ this, key.ToString().c_str(), value.ToString().c_str());
+ }
+ // We always keep track of num_calls_in_progress_, so that when this
+ // store is resumed, we still have a correct value of
+ // num_calls_in_progress_.
+ GPR_ASSERT(static_cast<int64_t>(num_calls_in_progress_) +
+ value.GetNumCallsInProgressDelta() >=
+ 0);
+ num_calls_in_progress_ += value.GetNumCallsInProgressDelta();
+}
+
+void PerBalancerStore::Suspend() {
+ suspended_ = true;
+ load_record_map_.clear();
+ gpr_log(GPR_DEBUG, "[PerBalancerStore %p] Suspended.", this);
+}
+
+void PerBalancerStore::Resume() {
+ suspended_ = false;
+ gpr_log(GPR_DEBUG, "[PerBalancerStore %p] Resumed.", this);
+}
+
+uint64_t PerBalancerStore::GetNumCallsInProgressForReport() {
+ GPR_ASSERT(!suspended_);
+ last_reported_num_calls_in_progress_ = num_calls_in_progress_;
+ return num_calls_in_progress_;
+}
+
+void PerHostStore::ReportStreamCreated(const grpc::string& lb_id,
+ const grpc::string& load_key) {
+ GPR_ASSERT(lb_id != kInvalidLbId);
+ SetUpForNewLbId(lb_id, load_key);
+ // Prior to this one, there was no load balancer receiving report, so we may
+ // have unassigned orphaned stores to assign to this new balancer.
+ // TODO(juanlishen): If the load key of this new stream is the same with
+ // some previously adopted orphan store, we may want to take the orphan to
+ // this stream. Need to discuss with LB team.
+ if (assigned_stores_.size() == 1) {
+ for (const auto& p : per_balancer_stores_) {
+ const grpc::string& other_lb_id = p.first;
+ const std::unique_ptr<PerBalancerStore>& orphaned_store = p.second;
+ if (other_lb_id != lb_id) {
+ orphaned_store->Resume();
+ AssignOrphanedStore(orphaned_store.get(), lb_id);
+ }
+ }
+ }
+ // The first connected balancer will adopt the kInvalidLbId.
+ if (per_balancer_stores_.size() == 1) {
+ SetUpForNewLbId(kInvalidLbId, "");
+ ReportStreamClosed(kInvalidLbId);
+ }
+}
+
+void PerHostStore::ReportStreamClosed(const grpc::string& lb_id) {
+ auto it_store_for_gone_lb = per_balancer_stores_.find(lb_id);
+ GPR_ASSERT(it_store_for_gone_lb != per_balancer_stores_.end());
+ // Remove this closed stream from our records.
+ GPR_ASSERT(UnorderedMapOfSetEraseKeyValue(
+ load_key_to_receiving_lb_ids_, it_store_for_gone_lb->second->load_key(),
+ lb_id));
+ std::set<PerBalancerStore*> orphaned_stores =
+ UnorderedMapOfSetExtract(assigned_stores_, lb_id);
+ // The stores that were assigned to this balancer are orphaned now. They
+ // should be re-assigned to other balancers which are still receiving reports.
+ for (PerBalancerStore* orphaned_store : orphaned_stores) {
+ const grpc::string* new_receiver = nullptr;
+ auto it = load_key_to_receiving_lb_ids_.find(orphaned_store->load_key());
+ if (it != load_key_to_receiving_lb_ids_.end()) {
+ // First, try to pick from the active balancers with the same load key.
+ new_receiver = RandomElement(it->second);
+ } else if (!assigned_stores_.empty()) {
+ // If failed, pick from all the remaining active balancers.
+ new_receiver = &(RandomElement(assigned_stores_)->first);
+ }
+ if (new_receiver != nullptr) {
+ AssignOrphanedStore(orphaned_store, *new_receiver);
+ } else {
+ // Load data for an LB ID that can't be assigned to any stream should
+ // be dropped.
+ orphaned_store->Suspend();
+ }
+ }
+}
+
+PerBalancerStore* PerHostStore::FindPerBalancerStore(
+ const grpc::string& lb_id) const {
+ return per_balancer_stores_.find(lb_id) != per_balancer_stores_.end()
+ ? per_balancer_stores_.find(lb_id)->second.get()
+ : nullptr;
+}
+
+const std::set<PerBalancerStore*>* PerHostStore::GetAssignedStores(
+ const grpc::string& lb_id) const {
+ auto it = assigned_stores_.find(lb_id);
+ if (it == assigned_stores_.end()) return nullptr;
+ return &(it->second);
+}
+
+void PerHostStore::AssignOrphanedStore(PerBalancerStore* orphaned_store,
+ const grpc::string& new_receiver) {
+ auto it = assigned_stores_.find(new_receiver);
+ GPR_ASSERT(it != assigned_stores_.end());
+ it->second.insert(orphaned_store);
+ gpr_log(GPR_INFO,
+ "[PerHostStore %p] Re-assigned orphaned store (%p) with original LB"
+ " ID of %s to new receiver %s",
+ this, orphaned_store, orphaned_store->lb_id().c_str(),
+ new_receiver.c_str());
+}
+
+void PerHostStore::SetUpForNewLbId(const grpc::string& lb_id,
+ const grpc::string& load_key) {
+ // The top-level caller (i.e., LoadReportService) should guarantee the
+ // lb_id is unique for each reporting stream.
+ GPR_ASSERT(per_balancer_stores_.find(lb_id) == per_balancer_stores_.end());
+ GPR_ASSERT(assigned_stores_.find(lb_id) == assigned_stores_.end());
+ load_key_to_receiving_lb_ids_[load_key].insert(lb_id);
+ std::unique_ptr<PerBalancerStore> per_balancer_store(
+ new PerBalancerStore(lb_id, load_key));
+ assigned_stores_[lb_id] = {per_balancer_store.get()};
+ per_balancer_stores_[lb_id] = std::move(per_balancer_store);
+}
+
+PerBalancerStore* LoadDataStore::FindPerBalancerStore(
+ const string& hostname, const string& lb_id) const {
+ auto it = per_host_stores_.find(hostname);
+ if (it != per_host_stores_.end()) {
+ const PerHostStore& per_host_store = it->second;
+ return per_host_store.FindPerBalancerStore(lb_id);
+ } else {
+ return nullptr;
+ }
+}
+
+void LoadDataStore::MergeRow(const grpc::string& hostname,
+ const LoadRecordKey& key,
+ const LoadRecordValue& value) {
+ PerBalancerStore* per_balancer_store =
+ FindPerBalancerStore(hostname, key.lb_id());
+ if (per_balancer_store != nullptr) {
+ per_balancer_store->MergeRow(key, value);
+ return;
+ }
+ // Unknown LB ID. Track it until its number of in-progress calls drops to
+ // zero.
+ int64_t in_progress_delta = value.GetNumCallsInProgressDelta();
+ if (in_progress_delta != 0) {
+ auto it_tracker = unknown_balancer_id_trackers_.find(key.lb_id());
+ if (it_tracker == unknown_balancer_id_trackers_.end()) {
+ gpr_log(
+ GPR_DEBUG,
+ "[LoadDataStore %p] Start tracking unknown balancer (lb_id_: %s).",
+ this, key.lb_id().c_str());
+ unknown_balancer_id_trackers_.insert(
+ {key.lb_id(), static_cast<uint64_t>(in_progress_delta)});
+ } else if ((it_tracker->second += in_progress_delta) == 0) {
+ unknown_balancer_id_trackers_.erase(it_tracker);
+ gpr_log(GPR_DEBUG,
+ "[LoadDataStore %p] Stop tracking unknown balancer (lb_id_: %s).",
+ this, key.lb_id().c_str());
+ }
+ }
+}
+
+const std::set<PerBalancerStore*>* LoadDataStore::GetAssignedStores(
+ const grpc::string& hostname, const grpc::string& lb_id) {
+ auto it = per_host_stores_.find(hostname);
+ if (it == per_host_stores_.end()) return nullptr;
+ return it->second.GetAssignedStores(lb_id);
+}
+
+void LoadDataStore::ReportStreamCreated(const grpc::string& hostname,
+ const grpc::string& lb_id,
+ const grpc::string& load_key) {
+ per_host_stores_[hostname].ReportStreamCreated(lb_id, load_key);
+}
+
+void LoadDataStore::ReportStreamClosed(const grpc::string& hostname,
+ const grpc::string& lb_id) {
+ auto it_per_host_store = per_host_stores_.find(hostname);
+ GPR_ASSERT(it_per_host_store != per_host_stores_.end());
+ it_per_host_store->second.ReportStreamClosed(lb_id);
+}
+
+} // namespace load_reporter
+} // namespace grpc
diff --git a/src/cpp/server/load_reporter/load_data_store.h b/src/cpp/server/load_reporter/load_data_store.h
new file mode 100644
index 0000000..feb8b2f
--- /dev/null
+++ b/src/cpp/server/load_reporter/load_data_store.h
@@ -0,0 +1,339 @@
+/*
+ *
+ * Copyright 2018 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_SRC_CPP_SERVER_LOAD_REPORTER_LOAD_DATA_STORE_H
+#define GRPC_SRC_CPP_SERVER_LOAD_REPORTER_LOAD_DATA_STORE_H
+
+#include <grpc/support/port_platform.h>
+
+#include <memory>
+#include <set>
+#include <unordered_map>
+
+#include <grpc/support/log.h>
+#include <grpcpp/impl/codegen/config.h>
+
+namespace grpc {
+namespace load_reporter {
+
+constexpr char kInvalidLbId[] = "<INVALID_LBID_238dsb234890rb>";
+constexpr uint8_t kLbIdLen = 8;
+
+// The load data storage is organized in hierarchy. The LoadDataStore is the
+// top-level data store. In LoadDataStore, for each host we keep a
+// PerHostStore, in which for each balancer we keep a PerBalancerStore. Each
+// PerBalancerStore maintains a map of load records, mapping from LoadRecordKey
+// to LoadRecordValue. The LoadRecordValue contains a map of customized call
+// metrics, mapping from a call metric name to the CallMetricValue.
+
+// The value of a customized call metric.
+class CallMetricValue {
+ public:
+ explicit CallMetricValue(uint64_t num_calls = 0,
+ double total_metric_value = 0)
+ : num_calls_(num_calls), total_metric_value_(total_metric_value) {}
+
+ void MergeFrom(CallMetricValue other) {
+ num_calls_ += other.num_calls_;
+ total_metric_value_ += other.total_metric_value_;
+ }
+
+ // Getters.
+ uint64_t num_calls() const { return num_calls_; }
+ double total_metric_value() const { return total_metric_value_; }
+
+ private:
+ // The number of calls that finished with this metric.
+ uint64_t num_calls_ = 0;
+ // The sum of metric values across all the calls that finished with this
+ // metric.
+ double total_metric_value_ = 0;
+};
+
+// The key of a load record.
+class LoadRecordKey {
+ public:
+ explicit LoadRecordKey(grpc::string lb_id, grpc::string lb_tag,
+ grpc::string user_id, grpc::string client_ip_hex)
+ : lb_id_(std::move(lb_id)),
+ lb_tag_(std::move(lb_tag)),
+ user_id_(std::move(user_id)),
+ client_ip_hex_(std::move(client_ip_hex)) {}
+
+ grpc::string ToString() const {
+ return "[lb_id_=" + lb_id_ + ", lb_tag_=" + lb_tag_ +
+ ", user_id_=" + user_id_ + ", client_ip_hex_=" + client_ip_hex_ +
+ "]";
+ }
+
+ bool operator==(const LoadRecordKey& other) const {
+ return lb_id_ == other.lb_id_ && lb_tag_ == other.lb_tag_ &&
+ user_id_ == other.user_id_ && client_ip_hex_ == other.client_ip_hex_;
+ }
+
+ // Getters.
+ const grpc::string& lb_id() const { return lb_id_; }
+ const grpc::string& lb_tag() const { return lb_tag_; }
+ const grpc::string& user_id() const { return user_id_; }
+ const grpc::string& client_ip_hex() const { return client_ip_hex_; }
+
+ struct Hasher {
+ void hash_combine(size_t* seed, const grpc::string& k) const {
+ *seed ^= std::hash<grpc::string>()(k) + 0x9e3779b9 + (*seed << 6) +
+ (*seed >> 2);
+ }
+
+ size_t operator()(const LoadRecordKey& k) const {
+ size_t h = 0;
+ hash_combine(&h, k.lb_id_);
+ hash_combine(&h, k.lb_tag_);
+ hash_combine(&h, k.user_id_);
+ hash_combine(&h, k.client_ip_hex_);
+ return h;
+ }
+ };
+
+ private:
+ grpc::string lb_id_;
+ grpc::string lb_tag_;
+ grpc::string user_id_;
+ grpc::string client_ip_hex_;
+};
+
+// The value of a load record.
+class LoadRecordValue {
+ public:
+ explicit LoadRecordValue(uint64_t start_count = 0, uint64_t ok_count = 0,
+ uint64_t error_count = 0, double bytes_sent = 0,
+ double bytes_recv = 0, double latency_ms = 0)
+ : start_count_(start_count),
+ ok_count_(ok_count),
+ error_count_(error_count),
+ bytes_sent_(bytes_sent),
+ bytes_recv_(bytes_recv),
+ latency_ms_(latency_ms) {}
+
+ void MergeFrom(const LoadRecordValue& other) {
+ start_count_ += other.start_count_;
+ ok_count_ += other.ok_count_;
+ error_count_ += other.error_count_;
+ bytes_sent_ += other.bytes_sent_;
+ bytes_recv_ += other.bytes_recv_;
+ latency_ms_ += other.latency_ms_;
+ for (const auto& p : other.call_metrics_) {
+ const grpc::string& key = p.first;
+ const CallMetricValue& value = p.second;
+ call_metrics_[key].MergeFrom(value);
+ }
+ }
+
+ int64_t GetNumCallsInProgressDelta() const {
+ return static_cast<int64_t>(start_count_ - ok_count_ - error_count_);
+ }
+
+ grpc::string ToString() const {
+ return "[start_count_=" + grpc::to_string(start_count_) +
+ ", ok_count_=" + grpc::to_string(ok_count_) +
+ ", error_count_=" + grpc::to_string(error_count_) +
+ ", bytes_sent_=" + grpc::to_string(bytes_sent_) +
+ ", bytes_recv_=" + grpc::to_string(bytes_recv_) +
+ ", latency_ms_=" + grpc::to_string(latency_ms_) + "]";
+ }
+
+ bool InsertCallMetric(const grpc::string& metric_name,
+ const CallMetricValue& metric_value) {
+ return call_metrics_.insert({metric_name, metric_value}).second;
+ }
+
+ // Getters.
+ uint64_t start_count() const { return start_count_; }
+ uint64_t ok_count() const { return ok_count_; }
+ uint64_t error_count() const { return error_count_; }
+ double bytes_sent() const { return bytes_sent_; }
+ double bytes_recv() const { return bytes_recv_; }
+ double latency_ms() const { return latency_ms_; }
+ const std::unordered_map<grpc::string, CallMetricValue>& call_metrics()
+ const {
+ return call_metrics_;
+ }
+
+ private:
+ uint64_t start_count_ = 0;
+ uint64_t ok_count_ = 0;
+ uint64_t error_count_ = 0;
+ double bytes_sent_ = 0;
+ double bytes_recv_ = 0;
+ double latency_ms_ = 0;
+ std::unordered_map<grpc::string, CallMetricValue> call_metrics_;
+};
+
+// Stores the data associated with a particular LB ID.
+class PerBalancerStore {
+ public:
+ using LoadRecordMap =
+ std::unordered_map<LoadRecordKey, LoadRecordValue, LoadRecordKey::Hasher>;
+
+ PerBalancerStore(grpc::string lb_id, grpc::string load_key)
+ : lb_id_(std::move(lb_id)), load_key_(std::move(load_key)) {}
+
+ // Merge a load record with the given key and value if the store is not
+ // suspended.
+ void MergeRow(const LoadRecordKey& key, const LoadRecordValue& value);
+
+ // Suspend this store, so that no detailed load data will be recorded.
+ void Suspend();
+ // Resume this store from suspension.
+ void Resume();
+ // Is this store suspended or not?
+ bool IsSuspended() const { return suspended_; }
+
+ bool IsNumCallsInProgressChangedSinceLastReport() const {
+ return num_calls_in_progress_ != last_reported_num_calls_in_progress_;
+ }
+
+ uint64_t GetNumCallsInProgressForReport();
+
+ grpc::string ToString() {
+ return "[PerBalancerStore lb_id_=" + lb_id_ + " load_key_=" + load_key_ +
+ "]";
+ }
+
+ void ClearLoadRecordMap() { load_record_map_.clear(); }
+
+ // Getters.
+ const grpc::string& lb_id() const { return lb_id_; }
+ const grpc::string& load_key() const { return load_key_; }
+ const LoadRecordMap& load_record_map() const { return load_record_map_; }
+
+ private:
+ grpc::string lb_id_;
+ // TODO(juanlishen): Use bytestring protobuf type?
+ grpc::string load_key_;
+ LoadRecordMap load_record_map_;
+ uint64_t num_calls_in_progress_ = 0;
+ uint64_t last_reported_num_calls_in_progress_ = 0;
+ bool suspended_ = false;
+};
+
+// Stores the data associated with a particular host.
+class PerHostStore {
+ public:
+ // When a report stream is created, a PerBalancerStore is created for the
+ // LB ID (guaranteed unique) associated with that stream. If it is the only
+ // active store, adopt all the orphaned stores. If it is the first created
+ // store, adopt the store of kInvalidLbId.
+ void ReportStreamCreated(const grpc::string& lb_id,
+ const grpc::string& load_key);
+
+ // When a report stream is closed, the PerBalancerStores assigned to the
+ // associate LB ID need to be re-assigned to other active balancers,
+ // ideally with the same load key. If there is no active balancer, we have
+ // to suspend those stores and drop the incoming load data until they are
+ // resumed.
+ void ReportStreamClosed(const grpc::string& lb_id);
+
+ // Returns null if not found. Caller doesn't own the returned store.
+ PerBalancerStore* FindPerBalancerStore(const grpc::string& lb_id) const;
+
+ // Returns null if lb_id is not found. The returned pointer points to the
+ // underlying data structure, which is not owned by the caller.
+ const std::set<PerBalancerStore*>* GetAssignedStores(
+ const grpc::string& lb_id) const;
+
+ private:
+ // Creates a PerBalancerStore for the given LB ID, assigns the store to
+ // itself, and records the LB ID to the load key.
+ void SetUpForNewLbId(const grpc::string& lb_id, const grpc::string& load_key);
+
+ void AssignOrphanedStore(PerBalancerStore* orphaned_store,
+ const grpc::string& new_receiver);
+
+ std::unordered_map<grpc::string, std::set<grpc::string>>
+ load_key_to_receiving_lb_ids_;
+
+ // Key: LB ID. The key set includes all the LB IDs that have been
+ // allocated for reporting streams so far.
+ // Value: the unique pointer to the PerBalancerStore of the LB ID.
+ std::unordered_map<grpc::string, std::unique_ptr<PerBalancerStore>>
+ per_balancer_stores_;
+
+ // Key: LB ID. The key set includes the LB IDs of the balancers that are
+ // currently receiving report.
+ // Value: the set of raw pointers to the PerBalancerStores assigned to the LB
+ // ID. Note that the sets in assigned_stores_ form a division of the value set
+ // of per_balancer_stores_.
+ std::unordered_map<grpc::string, std::set<PerBalancerStore*>>
+ assigned_stores_;
+};
+
+// Thread-unsafe two-level bookkeeper of all the load data.
+// Note: We never remove any store objects from this class, as per the
+// current spec. That's because premature removal of the store objects
+// may lead to loss of critical information, e.g., mapping from lb_id to
+// load_key, and the number of in-progress calls. Such loss will cause
+// information inconsistency when the balancer is re-connected. Keeping
+// all the stores should be fine for PerHostStore, since we assume there
+// should only be a few hostnames. But it's a potential problem for
+// PerBalancerStore.
+class LoadDataStore {
+ public:
+ // Returns null if not found. Caller doesn't own the returned store.
+ PerBalancerStore* FindPerBalancerStore(const grpc::string& hostname,
+ const grpc::string& lb_id) const;
+
+ // Returns null if hostname or lb_id is not found. The returned pointer points
+ // to the underlying data structure, which is not owned by the caller.
+ const std::set<PerBalancerStore*>* GetAssignedStores(const string& hostname,
+ const string& lb_id);
+
+ // If a PerBalancerStore can be found by the hostname and LB ID in
+ // LoadRecordKey, the load data will be merged to that store. Otherwise,
+ // only track the number of the in-progress calls for this unknown LB ID.
+ void MergeRow(const grpc::string& hostname, const LoadRecordKey& key,
+ const LoadRecordValue& value);
+
+ // Is the given lb_id a tracked unknown LB ID (i.e., the LB ID was associated
+ // with some received load data but unknown to this load data store)?
+ bool IsTrackedUnknownBalancerId(const grpc::string& lb_id) const {
+ return unknown_balancer_id_trackers_.find(lb_id) !=
+ unknown_balancer_id_trackers_.end();
+ }
+
+ // Wrapper around PerHostStore::ReportStreamCreated.
+ void ReportStreamCreated(const grpc::string& hostname,
+ const grpc::string& lb_id,
+ const grpc::string& load_key);
+
+ // Wrapper around PerHostStore::ReportStreamClosed.
+ void ReportStreamClosed(const grpc::string& hostname,
+ const grpc::string& lb_id);
+
+ private:
+ // Buffered data that was fetched from Census but hasn't been sent to
+ // balancer. We need to keep this data ourselves because Census will
+ // delete the data once it's returned.
+ std::unordered_map<grpc::string, PerHostStore> per_host_stores_;
+
+ // Tracks the number of in-progress calls for each unknown LB ID.
+ std::unordered_map<grpc::string, uint64_t> unknown_balancer_id_trackers_;
+};
+
+} // namespace load_reporter
+} // namespace grpc
+
+#endif // GRPC_SRC_CPP_SERVER_LOAD_REPORTER_LOAD_DATA_STORE_H
diff --git a/src/cpp/server/secure_server_credentials.cc b/src/cpp/server/secure_server_credentials.cc
index 1887109..a5af257 100644
--- a/src/cpp/server/secure_server_credentials.cc
+++ b/src/cpp/server/secure_server_credentials.cc
@@ -126,4 +126,18 @@
new SecureServerCredentials(c_creds));
}
+namespace experimental {
+
+std::shared_ptr<ServerCredentials> AltsServerCredentials(
+ const AltsServerCredentialsOptions& options) {
+ grpc_alts_credentials_options* c_options =
+ grpc_alts_credentials_server_options_create();
+ grpc_server_credentials* c_creds =
+ grpc_alts_server_credentials_create(c_options);
+ grpc_alts_credentials_options_destroy(c_options);
+ return std::shared_ptr<ServerCredentials>(
+ new SecureServerCredentials(c_creds));
+}
+
+} // namespace experimental
} // namespace grpc
diff --git a/src/cpp/util/byte_buffer_cc.cc b/src/cpp/util/byte_buffer_cc.cc
index fbc1768..8700f96 100644
--- a/src/cpp/util/byte_buffer_cc.cc
+++ b/src/cpp/util/byte_buffer_cc.cc
@@ -25,32 +25,6 @@
static internal::GrpcLibraryInitializer g_gli_initializer;
-ByteBuffer::ByteBuffer(const Slice* slices, size_t nslices) {
- // The following assertions check that the representation of a grpc::Slice is
- // identical to that of a grpc_slice: it has a grpc_slice field, and nothing
- // else.
- static_assert(std::is_same<decltype(slices[0].slice_), grpc_slice>::value,
- "Slice must have same representation as grpc_slice");
- static_assert(sizeof(Slice) == sizeof(grpc_slice),
- "Slice must have same representation as grpc_slice");
- // The following assertions check that the representation of a ByteBuffer is
- // identical to grpc_byte_buffer*: it has a grpc_byte_buffer* field,
- // and nothing else.
- static_assert(std::is_same<decltype(buffer_), grpc_byte_buffer*>::value,
- "ByteBuffer must have same representation as "
- "grpc_byte_buffer*");
- static_assert(sizeof(ByteBuffer) == sizeof(grpc_byte_buffer*),
- "ByteBuffer must have same representation as "
- "grpc_byte_buffer*");
- g_gli_initializer.summon(); // Make sure that initializer linked in
- // The const_cast is legal if grpc_raw_byte_buffer_create() does no more
- // than its advertised side effect of increasing the reference count of the
- // slices it processes, and such an increase does not affect the semantics
- // seen by the caller of this constructor.
- buffer_ = grpc_raw_byte_buffer_create(
- reinterpret_cast<grpc_slice*>(const_cast<Slice*>(slices)), nslices);
-}
-
Status ByteBuffer::Dump(std::vector<Slice>* slices) const {
slices->clear();
if (!buffer_) {
@@ -69,14 +43,6 @@
return Status::OK;
}
-size_t ByteBuffer::Length() const {
- if (buffer_) {
- return grpc_byte_buffer_length(buffer_);
- } else {
- return 0;
- }
-}
-
ByteBuffer::ByteBuffer(const ByteBuffer& buf)
: buffer_(grpc_byte_buffer_copy(buf.buffer_)) {}
@@ -90,10 +56,4 @@
return *this;
}
-void ByteBuffer::Swap(ByteBuffer* other) {
- grpc_byte_buffer* tmp = other->buffer_;
- other->buffer_ = buffer_;
- buffer_ = tmp;
-}
-
} // namespace grpc
diff --git a/src/cpp/util/slice_cc.cc b/src/cpp/util/slice_cc.cc
deleted file mode 100644
index c72dbdb..0000000
--- a/src/cpp/util/slice_cc.cc
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- *
- * 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.
- *
- */
-
-#include <grpc/slice.h>
-#include <grpcpp/support/slice.h>
-
-namespace grpc {
-
-Slice::Slice() : slice_(grpc_empty_slice()) {}
-
-Slice::~Slice() { grpc_slice_unref(slice_); }
-
-Slice::Slice(grpc_slice slice, AddRef) : slice_(grpc_slice_ref(slice)) {}
-
-Slice::Slice(grpc_slice slice, StealRef) : slice_(slice) {}
-
-Slice::Slice(size_t len) : slice_(grpc_slice_malloc(len)) {}
-
-Slice::Slice(const void* buf, size_t len)
- : slice_(
- grpc_slice_from_copied_buffer(static_cast<const char*>(buf), len)) {}
-
-Slice::Slice(const grpc::string& str)
- : slice_(grpc_slice_from_copied_buffer(str.c_str(), str.length())) {}
-
-Slice::Slice(const void* buf, size_t len, StaticSlice)
- : slice_(
- grpc_slice_from_static_buffer(static_cast<const char*>(buf), len)) {}
-
-Slice::Slice(const Slice& other) : slice_(grpc_slice_ref(other.slice_)) {}
-
-Slice::Slice(void* buf, size_t len, void (*destroy)(void*), void* user_data)
- : slice_(grpc_slice_new_with_user_data(buf, len, destroy, user_data)) {}
-
-Slice::Slice(void* buf, size_t len, void (*destroy)(void*, size_t))
- : slice_(grpc_slice_new_with_len(buf, len, destroy)) {}
-
-grpc_slice Slice::c_slice() const { return grpc_slice_ref(slice_); }
-
-} // namespace grpc
diff --git a/src/csharp/.editorconfig b/src/csharp/.editorconfig
index 7bc2bcc..fabce7f 100644
--- a/src/csharp/.editorconfig
+++ b/src/csharp/.editorconfig
@@ -1,5 +1,6 @@
root = true
[**]
+charset = utf-8 ; Implies no BOM.
end_of_line = LF
indent_style = space
indent_size = 4
diff --git a/src/csharp/.gitignore b/src/csharp/.gitignore
index fc2875a..6fd7648 100644
--- a/src/csharp/.gitignore
+++ b/src/csharp/.gitignore
@@ -1,15 +1,17 @@
-*.xproj.user
*.userprefs
-*.csproj.user
+*.user
*.lock.json
+/*.suo
+/*.sdf
+/.vs/
+bin/
+obj/
+*.nupkg
StyleCop.Cache
-test-results
-packages
-Grpc.v12.suo
-Grpc.sdf
+/packages/
+/protoc_plugins/
+test-results/
TestResult.xml
coverage_results.xml
/TestResults
-.vs/
-*.nupkg
diff --git a/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs b/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs
new file mode 100644
index 0000000..5418417
--- /dev/null
+++ b/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs
@@ -0,0 +1,58 @@
+#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.Threading;
+using System.Threading.Tasks;
+using Grpc.Core;
+
+namespace Grpc.Core.Testing
+{
+ /// <summary>
+ /// Creates test doubles for <c>ServerCallContext</c>.
+ /// </summary>
+ public static class TestServerCallContext
+ {
+ /// <summary>
+ /// Creates a test double for <c>ServerCallContext</c>. Only for testing.
+ /// Note: experimental API that can change or be removed without any prior notice.
+ /// </summary>
+ public static ServerCallContext Create(string method, string host, DateTime deadline, Metadata requestHeaders, CancellationToken cancellationToken,
+ string peer, AuthContext authContext, ContextPropagationToken contextPropagationToken,
+ Func<Metadata, Task> writeHeadersFunc, Func<WriteOptions> writeOptionsGetter, Action<WriteOptions> writeOptionsSetter)
+ {
+ return new ServerCallContext(null, method, host, deadline, requestHeaders, cancellationToken,
+ writeHeadersFunc, new WriteOptionsHolder(writeOptionsGetter, writeOptionsSetter),
+ () => peer, () => authContext, () => contextPropagationToken);
+ }
+
+ private class WriteOptionsHolder : IHasWriteOptions
+ {
+ Func<WriteOptions> writeOptionsGetter;
+ Action<WriteOptions> writeOptionsSetter;
+
+ public WriteOptionsHolder(Func<WriteOptions> writeOptionsGetter, Action<WriteOptions> writeOptionsSetter)
+ {
+ this.writeOptionsGetter = writeOptionsGetter;
+ this.writeOptionsSetter = writeOptionsSetter;
+ }
+
+ public WriteOptions WriteOptions { get => writeOptionsGetter(); set => writeOptionsSetter(value); }
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Core/NativeDeps.Mac.csproj.include b/src/csharp/Grpc.Core/NativeDeps.Mac.csproj.include
index f1b85c3..309e33d 100644
--- a/src/csharp/Grpc.Core/NativeDeps.Mac.csproj.include
+++ b/src/csharp/Grpc.Core/NativeDeps.Mac.csproj.include
@@ -1,13 +1,5 @@
<Project>
<ItemGroup>
- <!-- We are relying on run_tests.py to build grpc_csharp_ext with the right bitness
- and we copy it as both x86 (needed by net45) and x64 (needed by netcoreapp1.0) as we don't
- know which one will be needed to run the tests. -->
- <Content Include="..\..\..\libs\$(NativeDependenciesConfigurationUnix)\libgrpc_csharp_ext.dylib">
- <Link>libgrpc_csharp_ext.x86.dylib</Link>
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- <Pack>false</Pack>
- </Content>
<Content Include="..\..\..\libs\$(NativeDependenciesConfigurationUnix)\libgrpc_csharp_ext.dylib">
<Link>libgrpc_csharp_ext.x64.dylib</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
diff --git a/src/csharp/Grpc.Core/RpcException.cs b/src/csharp/Grpc.Core/RpcException.cs
index d2c912e..94429d7 100644
--- a/src/csharp/Grpc.Core/RpcException.cs
+++ b/src/csharp/Grpc.Core/RpcException.cs
@@ -73,6 +73,17 @@
}
/// <summary>
+ /// Returns the status code of the call, as a convenient alternative to <see cref="StatusCode">Status.StatusCode</see>.
+ /// </summary>
+ public StatusCode StatusCode
+ {
+ get
+ {
+ return status.StatusCode;
+ }
+ }
+
+ /// <summary>
/// Gets the call trailing metadata.
/// Trailers only have meaningful content for client-side calls (in which case they represent the trailing metadata sent by the server when closing the call).
/// Instances of <c>RpcException</c> thrown by the server-side part of the stack will have trailers always set to empty.
diff --git a/src/csharp/Grpc.Core/ServerCallContext.cs b/src/csharp/Grpc.Core/ServerCallContext.cs
index c63a4c4..74a7dea 100644
--- a/src/csharp/Grpc.Core/ServerCallContext.cs
+++ b/src/csharp/Grpc.Core/ServerCallContext.cs
@@ -36,14 +36,25 @@
private readonly Metadata requestHeaders;
private readonly CancellationToken cancellationToken;
private readonly Metadata responseTrailers = new Metadata();
+ private readonly Func<Metadata, Task> writeHeadersFunc;
+ private readonly IHasWriteOptions writeOptionsHolder;
+ private readonly Lazy<AuthContext> authContext;
+ private readonly Func<string> testingOnlyPeerGetter;
+ private readonly Func<AuthContext> testingOnlyAuthContextGetter;
+ private readonly Func<ContextPropagationToken> testingOnlyContextPropagationTokenFactory;
private Status status = Status.DefaultSuccess;
- private Func<Metadata, Task> writeHeadersFunc;
- private IHasWriteOptions writeOptionsHolder;
- private Lazy<AuthContext> authContext;
internal ServerCallContext(CallSafeHandle callHandle, string method, string host, DateTime deadline, Metadata requestHeaders, CancellationToken cancellationToken,
Func<Metadata, Task> writeHeadersFunc, IHasWriteOptions writeOptionsHolder)
+ : this(callHandle, method, host, deadline, requestHeaders, cancellationToken, writeHeadersFunc, writeOptionsHolder, null, null, null)
+ {
+ }
+
+ // Additional constructor params should be used for testing only
+ internal ServerCallContext(CallSafeHandle callHandle, string method, string host, DateTime deadline, Metadata requestHeaders, CancellationToken cancellationToken,
+ Func<Metadata, Task> writeHeadersFunc, IHasWriteOptions writeOptionsHolder,
+ Func<string> testingOnlyPeerGetter, Func<AuthContext> testingOnlyAuthContextGetter, Func<ContextPropagationToken> testingOnlyContextPropagationTokenFactory)
{
this.callHandle = callHandle;
this.method = method;
@@ -54,6 +65,9 @@
this.writeHeadersFunc = writeHeadersFunc;
this.writeOptionsHolder = writeOptionsHolder;
this.authContext = new Lazy<AuthContext>(GetAuthContextEager);
+ this.testingOnlyPeerGetter = testingOnlyPeerGetter;
+ this.testingOnlyAuthContextGetter = testingOnlyAuthContextGetter;
+ this.testingOnlyContextPropagationTokenFactory = testingOnlyContextPropagationTokenFactory;
}
/// <summary>
@@ -73,6 +87,10 @@
/// </summary>
public ContextPropagationToken CreatePropagationToken(ContextPropagationOptions options = null)
{
+ if (testingOnlyContextPropagationTokenFactory != null)
+ {
+ return testingOnlyContextPropagationTokenFactory();
+ }
return new ContextPropagationToken(callHandle, deadline, cancellationToken, options);
}
@@ -99,6 +117,10 @@
{
get
{
+ if (testingOnlyPeerGetter != null)
+ {
+ return testingOnlyPeerGetter();
+ }
// Getting the peer lazily is fine as the native call is guaranteed
// not to be disposed before user-supplied server side handler returns.
// Most users won't need to read this field anyway.
@@ -182,6 +204,10 @@
{
get
{
+ if (testingOnlyAuthContextGetter != null)
+ {
+ return testingOnlyAuthContextGetter();
+ }
return authContext.Value;
}
}
@@ -198,7 +224,7 @@
/// <summary>
/// Allows sharing write options between ServerCallContext and other objects.
/// </summary>
- public interface IHasWriteOptions
+ internal interface IHasWriteOptions
{
/// <summary>
/// Gets or sets the write options.
diff --git a/src/csharp/Grpc.Core/Version.csproj.include b/src/csharp/Grpc.Core/Version.csproj.include
index 9b55f24..f5d63b7 100755
--- a/src/csharp/Grpc.Core/Version.csproj.include
+++ b/src/csharp/Grpc.Core/Version.csproj.include
@@ -1,7 +1,7 @@
<!-- This file is generated -->
<Project>
<PropertyGroup>
- <GrpcCsharpVersion>1.11.0-dev</GrpcCsharpVersion>
- <GoogleProtobufVersion>3.3.0</GoogleProtobufVersion>
+ <GrpcCsharpVersion>1.13.0-dev</GrpcCsharpVersion>
+ <GoogleProtobufVersion>3.5.1</GoogleProtobufVersion>
</PropertyGroup>
</Project>
diff --git a/src/csharp/Grpc.Core/VersionInfo.cs b/src/csharp/Grpc.Core/VersionInfo.cs
index 2902aee..87eddda 100644
--- a/src/csharp/Grpc.Core/VersionInfo.cs
+++ b/src/csharp/Grpc.Core/VersionInfo.cs
@@ -33,11 +33,11 @@
/// <summary>
/// Current <c>AssemblyFileVersion</c> of gRPC C# assemblies
/// </summary>
- public const string CurrentAssemblyFileVersion = "1.11.0.0";
+ public const string CurrentAssemblyFileVersion = "1.13.0.0";
/// <summary>
/// Current version of gRPC C#
/// </summary>
- public const string CurrentVersion = "1.11.0-dev";
+ public const string CurrentVersion = "1.13.0-dev";
}
}
diff --git a/src/csharp/Grpc.Examples/Math.cs b/src/csharp/Grpc.Examples/Math.cs
index e5b76f8..4c3879f 100644
--- a/src/csharp/Grpc.Examples/Math.cs
+++ b/src/csharp/Grpc.Examples/Math.cs
@@ -1,5 +1,7 @@
-// Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: math/math.proto
+// <auto-generated>
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: math/math.proto
+// </auto-generated>
#pragma warning disable 1591, 0612, 3021
#region Designer generated code
@@ -47,6 +49,7 @@
#region Messages
public sealed partial class DivArgs : pb::IMessage<DivArgs> {
private static readonly pb::MessageParser<DivArgs> _parser = new pb::MessageParser<DivArgs>(() => new DivArgs());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<DivArgs> Parser { get { return _parser; } }
@@ -71,6 +74,7 @@
public DivArgs(DivArgs other) : this() {
dividend_ = other.dividend_;
divisor_ = other.divisor_;
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -115,7 +119,7 @@
}
if (Dividend != other.Dividend) return false;
if (Divisor != other.Divisor) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -123,6 +127,9 @@
int hash = 1;
if (Dividend != 0L) hash ^= Dividend.GetHashCode();
if (Divisor != 0L) hash ^= Divisor.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -141,6 +148,9 @@
output.WriteRawTag(16);
output.WriteInt64(Divisor);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -152,6 +162,9 @@
if (Divisor != 0L) {
size += 1 + pb::CodedOutputStream.ComputeInt64Size(Divisor);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -166,6 +179,7 @@
if (other.Divisor != 0L) {
Divisor = other.Divisor;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -174,7 +188,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 8: {
Dividend = input.ReadInt64();
@@ -192,6 +206,7 @@
public sealed partial class DivReply : pb::IMessage<DivReply> {
private static readonly pb::MessageParser<DivReply> _parser = new pb::MessageParser<DivReply>(() => new DivReply());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<DivReply> Parser { get { return _parser; } }
@@ -216,6 +231,7 @@
public DivReply(DivReply other) : this() {
quotient_ = other.quotient_;
remainder_ = other.remainder_;
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -260,7 +276,7 @@
}
if (Quotient != other.Quotient) return false;
if (Remainder != other.Remainder) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -268,6 +284,9 @@
int hash = 1;
if (Quotient != 0L) hash ^= Quotient.GetHashCode();
if (Remainder != 0L) hash ^= Remainder.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -286,6 +305,9 @@
output.WriteRawTag(16);
output.WriteInt64(Remainder);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -297,6 +319,9 @@
if (Remainder != 0L) {
size += 1 + pb::CodedOutputStream.ComputeInt64Size(Remainder);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -311,6 +336,7 @@
if (other.Remainder != 0L) {
Remainder = other.Remainder;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -319,7 +345,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 8: {
Quotient = input.ReadInt64();
@@ -337,6 +363,7 @@
public sealed partial class FibArgs : pb::IMessage<FibArgs> {
private static readonly pb::MessageParser<FibArgs> _parser = new pb::MessageParser<FibArgs>(() => new FibArgs());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<FibArgs> Parser { get { return _parser; } }
@@ -360,6 +387,7 @@
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public FibArgs(FibArgs other) : this() {
limit_ = other.limit_;
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -392,13 +420,16 @@
return true;
}
if (Limit != other.Limit) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Limit != 0L) hash ^= Limit.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -413,6 +444,9 @@
output.WriteRawTag(8);
output.WriteInt64(Limit);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -421,6 +455,9 @@
if (Limit != 0L) {
size += 1 + pb::CodedOutputStream.ComputeInt64Size(Limit);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -432,6 +469,7 @@
if (other.Limit != 0L) {
Limit = other.Limit;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -440,7 +478,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 8: {
Limit = input.ReadInt64();
@@ -454,6 +492,7 @@
public sealed partial class Num : pb::IMessage<Num> {
private static readonly pb::MessageParser<Num> _parser = new pb::MessageParser<Num>(() => new Num());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<Num> Parser { get { return _parser; } }
@@ -477,6 +516,7 @@
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Num(Num other) : this() {
num_ = other.num_;
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -509,13 +549,16 @@
return true;
}
if (Num_ != other.Num_) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Num_ != 0L) hash ^= Num_.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -530,6 +573,9 @@
output.WriteRawTag(8);
output.WriteInt64(Num_);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -538,6 +584,9 @@
if (Num_ != 0L) {
size += 1 + pb::CodedOutputStream.ComputeInt64Size(Num_);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -549,6 +598,7 @@
if (other.Num_ != 0L) {
Num_ = other.Num_;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -557,7 +607,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 8: {
Num_ = input.ReadInt64();
@@ -571,6 +621,7 @@
public sealed partial class FibReply : pb::IMessage<FibReply> {
private static readonly pb::MessageParser<FibReply> _parser = new pb::MessageParser<FibReply>(() => new FibReply());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<FibReply> Parser { get { return _parser; } }
@@ -594,6 +645,7 @@
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public FibReply(FibReply other) : this() {
count_ = other.count_;
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -626,13 +678,16 @@
return true;
}
if (Count != other.Count) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Count != 0L) hash ^= Count.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -647,6 +702,9 @@
output.WriteRawTag(8);
output.WriteInt64(Count);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -655,6 +713,9 @@
if (Count != 0L) {
size += 1 + pb::CodedOutputStream.ComputeInt64Size(Count);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -666,6 +727,7 @@
if (other.Count != 0L) {
Count = other.Count;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -674,7 +736,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 8: {
Count = input.ReadInt64();
diff --git a/src/csharp/Grpc.HealthCheck/Health.cs b/src/csharp/Grpc.HealthCheck/Health.cs
index b9880d9..a90f261 100644
--- a/src/csharp/Grpc.HealthCheck/Health.cs
+++ b/src/csharp/Grpc.HealthCheck/Health.cs
@@ -1,5 +1,7 @@
-// Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: grpc/health/v1/health.proto
+// <auto-generated>
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: grpc/health/v1/health.proto
+// </auto-generated>
#pragma warning disable 1591, 0612, 3021
#region Designer generated code
@@ -29,7 +31,9 @@
"ZXJ2aW5nU3RhdHVzEgsKB1VOS05PV04QABILCgdTRVJWSU5HEAESDwoLTk9U",
"X1NFUlZJTkcQAjJaCgZIZWFsdGgSUAoFQ2hlY2sSIi5ncnBjLmhlYWx0aC52",
"MS5IZWFsdGhDaGVja1JlcXVlc3QaIy5ncnBjLmhlYWx0aC52MS5IZWFsdGhD",
- "aGVja1Jlc3BvbnNlQhGqAg5HcnBjLkhlYWx0aC5WMWIGcHJvdG8z"));
+ "aGVja1Jlc3BvbnNlQmEKEWlvLmdycGMuaGVhbHRoLnYxQgtIZWFsdGhQcm90",
+ "b1ABWixnb29nbGUuZ29sYW5nLm9yZy9ncnBjL2hlYWx0aC9ncnBjX2hlYWx0",
+ "aF92MaoCDkdycGMuSGVhbHRoLlYxYgZwcm90bzM="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
@@ -43,6 +47,7 @@
#region Messages
public sealed partial class HealthCheckRequest : pb::IMessage<HealthCheckRequest> {
private static readonly pb::MessageParser<HealthCheckRequest> _parser = new pb::MessageParser<HealthCheckRequest>(() => new HealthCheckRequest());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<HealthCheckRequest> Parser { get { return _parser; } }
@@ -66,6 +71,7 @@
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public HealthCheckRequest(HealthCheckRequest other) : this() {
service_ = other.service_;
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -98,13 +104,16 @@
return true;
}
if (Service != other.Service) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Service.Length != 0) hash ^= Service.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -119,6 +128,9 @@
output.WriteRawTag(10);
output.WriteString(Service);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -127,6 +139,9 @@
if (Service.Length != 0) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(Service);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -138,6 +153,7 @@
if (other.Service.Length != 0) {
Service = other.Service;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -146,7 +162,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
Service = input.ReadString();
@@ -160,6 +176,7 @@
public sealed partial class HealthCheckResponse : pb::IMessage<HealthCheckResponse> {
private static readonly pb::MessageParser<HealthCheckResponse> _parser = new pb::MessageParser<HealthCheckResponse>(() => new HealthCheckResponse());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<HealthCheckResponse> Parser { get { return _parser; } }
@@ -183,6 +200,7 @@
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public HealthCheckResponse(HealthCheckResponse other) : this() {
status_ = other.status_;
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -215,13 +233,16 @@
return true;
}
if (Status != other.Status) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Status != 0) hash ^= Status.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -236,6 +257,9 @@
output.WriteRawTag(8);
output.WriteEnum((int) Status);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -244,6 +268,9 @@
if (Status != 0) {
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Status);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -255,6 +282,7 @@
if (other.Status != 0) {
Status = other.Status;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -263,7 +291,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 8: {
status_ = (global::Grpc.Health.V1.HealthCheckResponse.Types.ServingStatus) input.ReadEnum();
diff --git a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
index 1d80bcd..a26f483 100644
--- a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
+++ b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
@@ -3,7 +3,7 @@
// source: grpc/health/v1/health.proto
// </auto-generated>
// Original file comments:
-// Copyright 2015 gRPC authors.
+// Copyright 2015 The gRPC Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -17,6 +17,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
+// The canonical version of this proto can be found at
+// https://github.com/grpc/grpc-proto/blob/master/grpc/health/v1/health.proto
+//
#pragma warning disable 1591
#region Designer generated code
diff --git a/src/csharp/Grpc.IntegrationTesting/BenchmarkService.cs b/src/csharp/Grpc.IntegrationTesting/BenchmarkService.cs
new file mode 100644
index 0000000..bc8c103
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting/BenchmarkService.cs
@@ -0,0 +1,48 @@
+// <auto-generated>
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: src/proto/grpc/testing/benchmark_service.proto
+// </auto-generated>
+#pragma warning disable 1591, 0612, 3021
+#region Designer generated code
+
+using pb = global::Google.Protobuf;
+using pbc = global::Google.Protobuf.Collections;
+using pbr = global::Google.Protobuf.Reflection;
+using scg = global::System.Collections.Generic;
+namespace Grpc.Testing {
+
+ /// <summary>Holder for reflection information generated from src/proto/grpc/testing/benchmark_service.proto</summary>
+ public static partial class BenchmarkServiceReflection {
+
+ #region Descriptor
+ /// <summary>File descriptor for src/proto/grpc/testing/benchmark_service.proto</summary>
+ public static pbr::FileDescriptor Descriptor {
+ get { return descriptor; }
+ }
+ private static pbr::FileDescriptor descriptor;
+
+ static BenchmarkServiceReflection() {
+ byte[] descriptorData = global::System.Convert.FromBase64String(
+ string.Concat(
+ "Ci5zcmMvcHJvdG8vZ3JwYy90ZXN0aW5nL2JlbmNobWFya19zZXJ2aWNlLnBy",
+ "b3RvEgxncnBjLnRlc3RpbmcaJXNyYy9wcm90by9ncnBjL3Rlc3RpbmcvbWVz",
+ "c2FnZXMucHJvdG8ypgMKEEJlbmNobWFya1NlcnZpY2USRgoJVW5hcnlDYWxs",
+ "EhsuZ3JwYy50ZXN0aW5nLlNpbXBsZVJlcXVlc3QaHC5ncnBjLnRlc3Rpbmcu",
+ "U2ltcGxlUmVzcG9uc2USTgoNU3RyZWFtaW5nQ2FsbBIbLmdycGMudGVzdGlu",
+ "Zy5TaW1wbGVSZXF1ZXN0GhwuZ3JwYy50ZXN0aW5nLlNpbXBsZVJlc3BvbnNl",
+ "KAEwARJSChNTdHJlYW1pbmdGcm9tQ2xpZW50EhsuZ3JwYy50ZXN0aW5nLlNp",
+ "bXBsZVJlcXVlc3QaHC5ncnBjLnRlc3RpbmcuU2ltcGxlUmVzcG9uc2UoARJS",
+ "ChNTdHJlYW1pbmdGcm9tU2VydmVyEhsuZ3JwYy50ZXN0aW5nLlNpbXBsZVJl",
+ "cXVlc3QaHC5ncnBjLnRlc3RpbmcuU2ltcGxlUmVzcG9uc2UwARJSChFTdHJl",
+ "YW1pbmdCb3RoV2F5cxIbLmdycGMudGVzdGluZy5TaW1wbGVSZXF1ZXN0Ghwu",
+ "Z3JwYy50ZXN0aW5nLlNpbXBsZVJlc3BvbnNlKAEwAWIGcHJvdG8z"));
+ descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+ new pbr::FileDescriptor[] { global::Grpc.Testing.MessagesReflection.Descriptor, },
+ new pbr::GeneratedClrTypeInfo(null, null));
+ }
+ #endregion
+
+ }
+}
+
+#endregion Designer generated code
diff --git a/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs
new file mode 100644
index 0000000..20b933f
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs
@@ -0,0 +1,329 @@
+// <auto-generated>
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: src/proto/grpc/testing/benchmark_service.proto
+// </auto-generated>
+// Original file comments:
+// 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.
+//
+// An integration test service that covers all the method signature permutations
+// of unary/streaming requests/responses.
+#pragma warning disable 1591
+#region Designer generated code
+
+using grpc = global::Grpc.Core;
+
+namespace Grpc.Testing {
+ public static partial class BenchmarkService
+ {
+ static readonly string __ServiceName = "grpc.testing.BenchmarkService";
+
+ static readonly grpc::Marshaller<global::Grpc.Testing.SimpleRequest> __Marshaller_SimpleRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.SimpleRequest.Parser.ParseFrom);
+ static readonly grpc::Marshaller<global::Grpc.Testing.SimpleResponse> __Marshaller_SimpleResponse = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.SimpleResponse.Parser.ParseFrom);
+
+ static readonly grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> __Method_UnaryCall = new grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse>(
+ grpc::MethodType.Unary,
+ __ServiceName,
+ "UnaryCall",
+ __Marshaller_SimpleRequest,
+ __Marshaller_SimpleResponse);
+
+ static readonly grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> __Method_StreamingCall = new grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse>(
+ grpc::MethodType.DuplexStreaming,
+ __ServiceName,
+ "StreamingCall",
+ __Marshaller_SimpleRequest,
+ __Marshaller_SimpleResponse);
+
+ static readonly grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> __Method_StreamingFromClient = new grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse>(
+ grpc::MethodType.ClientStreaming,
+ __ServiceName,
+ "StreamingFromClient",
+ __Marshaller_SimpleRequest,
+ __Marshaller_SimpleResponse);
+
+ static readonly grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> __Method_StreamingFromServer = new grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse>(
+ grpc::MethodType.ServerStreaming,
+ __ServiceName,
+ "StreamingFromServer",
+ __Marshaller_SimpleRequest,
+ __Marshaller_SimpleResponse);
+
+ static readonly grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> __Method_StreamingBothWays = new grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse>(
+ grpc::MethodType.DuplexStreaming,
+ __ServiceName,
+ "StreamingBothWays",
+ __Marshaller_SimpleRequest,
+ __Marshaller_SimpleResponse);
+
+ /// <summary>Service descriptor</summary>
+ public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
+ {
+ get { return global::Grpc.Testing.BenchmarkServiceReflection.Descriptor.Services[0]; }
+ }
+
+ /// <summary>Base class for server-side implementations of BenchmarkService</summary>
+ public abstract partial class BenchmarkServiceBase
+ {
+ /// <summary>
+ /// One request followed by one response.
+ /// The server returns the client payload as-is.
+ /// </summary>
+ /// <param name="request">The request received from the client.</param>
+ /// <param name="context">The context of the server-side call handler being invoked.</param>
+ /// <returns>The response to send back to the client (wrapped by a task).</returns>
+ public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.SimpleResponse> UnaryCall(global::Grpc.Testing.SimpleRequest request, grpc::ServerCallContext context)
+ {
+ throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+ }
+
+ /// <summary>
+ /// Repeated sequence of one request followed by one response.
+ /// Should be called streaming ping-pong
+ /// The server returns the client payload as-is on each response
+ /// </summary>
+ /// <param name="requestStream">Used for reading requests from the client.</param>
+ /// <param name="responseStream">Used for sending responses back to the client.</param>
+ /// <param name="context">The context of the server-side call handler being invoked.</param>
+ /// <returns>A task indicating completion of the handler.</returns>
+ public virtual global::System.Threading.Tasks.Task StreamingCall(grpc::IAsyncStreamReader<global::Grpc.Testing.SimpleRequest> requestStream, grpc::IServerStreamWriter<global::Grpc.Testing.SimpleResponse> responseStream, grpc::ServerCallContext context)
+ {
+ throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+ }
+
+ /// <summary>
+ /// Single-sided unbounded streaming from client to server
+ /// The server returns the client payload as-is once the client does WritesDone
+ /// </summary>
+ /// <param name="requestStream">Used for reading requests from the client.</param>
+ /// <param name="context">The context of the server-side call handler being invoked.</param>
+ /// <returns>The response to send back to the client (wrapped by a task).</returns>
+ public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.SimpleResponse> StreamingFromClient(grpc::IAsyncStreamReader<global::Grpc.Testing.SimpleRequest> requestStream, grpc::ServerCallContext context)
+ {
+ throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+ }
+
+ /// <summary>
+ /// Single-sided unbounded streaming from server to client
+ /// The server repeatedly returns the client payload as-is
+ /// </summary>
+ /// <param name="request">The request received from the client.</param>
+ /// <param name="responseStream">Used for sending responses back to the client.</param>
+ /// <param name="context">The context of the server-side call handler being invoked.</param>
+ /// <returns>A task indicating completion of the handler.</returns>
+ public virtual global::System.Threading.Tasks.Task StreamingFromServer(global::Grpc.Testing.SimpleRequest request, grpc::IServerStreamWriter<global::Grpc.Testing.SimpleResponse> responseStream, grpc::ServerCallContext context)
+ {
+ throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+ }
+
+ /// <summary>
+ /// Two-sided unbounded streaming between server to client
+ /// Both sides send the content of their own choice to the other
+ /// </summary>
+ /// <param name="requestStream">Used for reading requests from the client.</param>
+ /// <param name="responseStream">Used for sending responses back to the client.</param>
+ /// <param name="context">The context of the server-side call handler being invoked.</param>
+ /// <returns>A task indicating completion of the handler.</returns>
+ public virtual global::System.Threading.Tasks.Task StreamingBothWays(grpc::IAsyncStreamReader<global::Grpc.Testing.SimpleRequest> requestStream, grpc::IServerStreamWriter<global::Grpc.Testing.SimpleResponse> responseStream, grpc::ServerCallContext context)
+ {
+ throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+ }
+
+ }
+
+ /// <summary>Client for BenchmarkService</summary>
+ public partial class BenchmarkServiceClient : grpc::ClientBase<BenchmarkServiceClient>
+ {
+ /// <summary>Creates a new client for BenchmarkService</summary>
+ /// <param name="channel">The channel to use to make remote calls.</param>
+ public BenchmarkServiceClient(grpc::Channel channel) : base(channel)
+ {
+ }
+ /// <summary>Creates a new client for BenchmarkService that uses a custom <c>CallInvoker</c>.</summary>
+ /// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
+ public BenchmarkServiceClient(grpc::CallInvoker callInvoker) : base(callInvoker)
+ {
+ }
+ /// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
+ protected BenchmarkServiceClient() : base()
+ {
+ }
+ /// <summary>Protected constructor to allow creation of configured clients.</summary>
+ /// <param name="configuration">The client configuration.</param>
+ protected BenchmarkServiceClient(ClientBaseConfiguration configuration) : base(configuration)
+ {
+ }
+
+ /// <summary>
+ /// One request followed by one response.
+ /// The server returns the client payload as-is.
+ /// </summary>
+ /// <param name="request">The request to send to the server.</param>
+ /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+ /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+ /// <param name="cancellationToken">An optional token for canceling the call.</param>
+ /// <returns>The response received from the server.</returns>
+ public virtual global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+ {
+ return UnaryCall(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+ }
+ /// <summary>
+ /// One request followed by one response.
+ /// The server returns the client payload as-is.
+ /// </summary>
+ /// <param name="request">The request to send to the server.</param>
+ /// <param name="options">The options for the call.</param>
+ /// <returns>The response received from the server.</returns>
+ public virtual global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, grpc::CallOptions options)
+ {
+ return CallInvoker.BlockingUnaryCall(__Method_UnaryCall, null, options, request);
+ }
+ /// <summary>
+ /// One request followed by one response.
+ /// The server returns the client payload as-is.
+ /// </summary>
+ /// <param name="request">The request to send to the server.</param>
+ /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+ /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+ /// <param name="cancellationToken">An optional token for canceling the call.</param>
+ /// <returns>The call object.</returns>
+ public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+ {
+ return UnaryCallAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+ }
+ /// <summary>
+ /// One request followed by one response.
+ /// The server returns the client payload as-is.
+ /// </summary>
+ /// <param name="request">The request to send to the server.</param>
+ /// <param name="options">The options for the call.</param>
+ /// <returns>The call object.</returns>
+ public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, grpc::CallOptions options)
+ {
+ return CallInvoker.AsyncUnaryCall(__Method_UnaryCall, null, options, request);
+ }
+ /// <summary>
+ /// Repeated sequence of one request followed by one response.
+ /// Should be called streaming ping-pong
+ /// The server returns the client payload as-is on each response
+ /// </summary>
+ /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+ /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+ /// <param name="cancellationToken">An optional token for canceling the call.</param>
+ /// <returns>The call object.</returns>
+ public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingCall(grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+ {
+ return StreamingCall(new grpc::CallOptions(headers, deadline, cancellationToken));
+ }
+ /// <summary>
+ /// Repeated sequence of one request followed by one response.
+ /// Should be called streaming ping-pong
+ /// The server returns the client payload as-is on each response
+ /// </summary>
+ /// <param name="options">The options for the call.</param>
+ /// <returns>The call object.</returns>
+ public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingCall(grpc::CallOptions options)
+ {
+ return CallInvoker.AsyncDuplexStreamingCall(__Method_StreamingCall, null, options);
+ }
+ /// <summary>
+ /// Single-sided unbounded streaming from client to server
+ /// The server returns the client payload as-is once the client does WritesDone
+ /// </summary>
+ /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+ /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+ /// <param name="cancellationToken">An optional token for canceling the call.</param>
+ /// <returns>The call object.</returns>
+ public virtual grpc::AsyncClientStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingFromClient(grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+ {
+ return StreamingFromClient(new grpc::CallOptions(headers, deadline, cancellationToken));
+ }
+ /// <summary>
+ /// Single-sided unbounded streaming from client to server
+ /// The server returns the client payload as-is once the client does WritesDone
+ /// </summary>
+ /// <param name="options">The options for the call.</param>
+ /// <returns>The call object.</returns>
+ public virtual grpc::AsyncClientStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingFromClient(grpc::CallOptions options)
+ {
+ return CallInvoker.AsyncClientStreamingCall(__Method_StreamingFromClient, null, options);
+ }
+ /// <summary>
+ /// Single-sided unbounded streaming from server to client
+ /// The server repeatedly returns the client payload as-is
+ /// </summary>
+ /// <param name="request">The request to send to the server.</param>
+ /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+ /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+ /// <param name="cancellationToken">An optional token for canceling the call.</param>
+ /// <returns>The call object.</returns>
+ public virtual grpc::AsyncServerStreamingCall<global::Grpc.Testing.SimpleResponse> StreamingFromServer(global::Grpc.Testing.SimpleRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+ {
+ return StreamingFromServer(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+ }
+ /// <summary>
+ /// Single-sided unbounded streaming from server to client
+ /// The server repeatedly returns the client payload as-is
+ /// </summary>
+ /// <param name="request">The request to send to the server.</param>
+ /// <param name="options">The options for the call.</param>
+ /// <returns>The call object.</returns>
+ public virtual grpc::AsyncServerStreamingCall<global::Grpc.Testing.SimpleResponse> StreamingFromServer(global::Grpc.Testing.SimpleRequest request, grpc::CallOptions options)
+ {
+ return CallInvoker.AsyncServerStreamingCall(__Method_StreamingFromServer, null, options, request);
+ }
+ /// <summary>
+ /// Two-sided unbounded streaming between server to client
+ /// Both sides send the content of their own choice to the other
+ /// </summary>
+ /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+ /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+ /// <param name="cancellationToken">An optional token for canceling the call.</param>
+ /// <returns>The call object.</returns>
+ public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingBothWays(grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+ {
+ return StreamingBothWays(new grpc::CallOptions(headers, deadline, cancellationToken));
+ }
+ /// <summary>
+ /// Two-sided unbounded streaming between server to client
+ /// Both sides send the content of their own choice to the other
+ /// </summary>
+ /// <param name="options">The options for the call.</param>
+ /// <returns>The call object.</returns>
+ public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingBothWays(grpc::CallOptions options)
+ {
+ return CallInvoker.AsyncDuplexStreamingCall(__Method_StreamingBothWays, null, options);
+ }
+ /// <summary>Creates a new instance of client from given <c>ClientBaseConfiguration</c>.</summary>
+ protected override BenchmarkServiceClient NewInstance(ClientBaseConfiguration configuration)
+ {
+ return new BenchmarkServiceClient(configuration);
+ }
+ }
+
+ /// <summary>Creates service definition that can be registered with a server</summary>
+ /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
+ public static grpc::ServerServiceDefinition BindService(BenchmarkServiceBase serviceImpl)
+ {
+ return grpc::ServerServiceDefinition.CreateBuilder()
+ .AddMethod(__Method_UnaryCall, serviceImpl.UnaryCall)
+ .AddMethod(__Method_StreamingCall, serviceImpl.StreamingCall)
+ .AddMethod(__Method_StreamingFromClient, serviceImpl.StreamingFromClient)
+ .AddMethod(__Method_StreamingFromServer, serviceImpl.StreamingFromServer)
+ .AddMethod(__Method_StreamingBothWays, serviceImpl.StreamingBothWays).Build();
+ }
+
+ }
+}
+#endregion
diff --git a/src/csharp/Grpc.IntegrationTesting/Control.cs b/src/csharp/Grpc.IntegrationTesting/Control.cs
index 8795728..f3284a5 100644
--- a/src/csharp/Grpc.IntegrationTesting/Control.cs
+++ b/src/csharp/Grpc.IntegrationTesting/Control.cs
@@ -1,5 +1,7 @@
-// Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: src/proto/grpc/testing/control.proto
+// <auto-generated>
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: src/proto/grpc/testing/control.proto
+// </auto-generated>
#pragma warning disable 1591, 0612, 3021
#region Designer generated code
@@ -167,6 +169,7 @@
/// </summary>
public sealed partial class PoissonParams : pb::IMessage<PoissonParams> {
private static readonly pb::MessageParser<PoissonParams> _parser = new pb::MessageParser<PoissonParams>(() => new PoissonParams());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<PoissonParams> Parser { get { return _parser; } }
@@ -190,6 +193,7 @@
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public PoissonParams(PoissonParams other) : this() {
offeredLoad_ = other.offeredLoad_;
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -224,14 +228,17 @@
if (ReferenceEquals(other, this)) {
return true;
}
- if (OfferedLoad != other.OfferedLoad) return false;
- return true;
+ if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(OfferedLoad, other.OfferedLoad)) return false;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
- if (OfferedLoad != 0D) hash ^= OfferedLoad.GetHashCode();
+ if (OfferedLoad != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(OfferedLoad);
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -246,6 +253,9 @@
output.WriteRawTag(9);
output.WriteDouble(OfferedLoad);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -254,6 +264,9 @@
if (OfferedLoad != 0D) {
size += 1 + 8;
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -265,6 +278,7 @@
if (other.OfferedLoad != 0D) {
OfferedLoad = other.OfferedLoad;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -273,7 +287,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 9: {
OfferedLoad = input.ReadDouble();
@@ -291,6 +305,7 @@
/// </summary>
public sealed partial class ClosedLoopParams : pb::IMessage<ClosedLoopParams> {
private static readonly pb::MessageParser<ClosedLoopParams> _parser = new pb::MessageParser<ClosedLoopParams>(() => new ClosedLoopParams());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<ClosedLoopParams> Parser { get { return _parser; } }
@@ -313,6 +328,7 @@
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ClosedLoopParams(ClosedLoopParams other) : this() {
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -333,12 +349,15 @@
if (ReferenceEquals(other, this)) {
return true;
}
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -349,11 +368,17 @@
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -362,6 +387,7 @@
if (other == null) {
return;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -370,7 +396,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
}
}
@@ -380,6 +406,7 @@
public sealed partial class LoadParams : pb::IMessage<LoadParams> {
private static readonly pb::MessageParser<LoadParams> _parser = new pb::MessageParser<LoadParams>(() => new LoadParams());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<LoadParams> Parser { get { return _parser; } }
@@ -411,6 +438,7 @@
break;
}
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -475,7 +503,7 @@
if (!object.Equals(ClosedLoop, other.ClosedLoop)) return false;
if (!object.Equals(Poisson, other.Poisson)) return false;
if (LoadCase != other.LoadCase) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -484,6 +512,9 @@
if (loadCase_ == LoadOneofCase.ClosedLoop) hash ^= ClosedLoop.GetHashCode();
if (loadCase_ == LoadOneofCase.Poisson) hash ^= Poisson.GetHashCode();
hash ^= (int) loadCase_;
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -502,6 +533,9 @@
output.WriteRawTag(18);
output.WriteMessage(Poisson);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -513,6 +547,9 @@
if (loadCase_ == LoadOneofCase.Poisson) {
size += 1 + pb::CodedOutputStream.ComputeMessageSize(Poisson);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -536,6 +573,7 @@
break;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -544,7 +582,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
global::Grpc.Testing.ClosedLoopParams subBuilder = new global::Grpc.Testing.ClosedLoopParams();
@@ -575,6 +613,7 @@
/// </summary>
public sealed partial class SecurityParams : pb::IMessage<SecurityParams> {
private static readonly pb::MessageParser<SecurityParams> _parser = new pb::MessageParser<SecurityParams>(() => new SecurityParams());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<SecurityParams> Parser { get { return _parser; } }
@@ -600,6 +639,7 @@
useTestCa_ = other.useTestCa_;
serverHostOverride_ = other.serverHostOverride_;
credType_ = other.credType_;
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -656,7 +696,7 @@
if (UseTestCa != other.UseTestCa) return false;
if (ServerHostOverride != other.ServerHostOverride) return false;
if (CredType != other.CredType) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -665,6 +705,9 @@
if (UseTestCa != false) hash ^= UseTestCa.GetHashCode();
if (ServerHostOverride.Length != 0) hash ^= ServerHostOverride.GetHashCode();
if (CredType.Length != 0) hash ^= CredType.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -687,6 +730,9 @@
output.WriteRawTag(26);
output.WriteString(CredType);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -701,6 +747,9 @@
if (CredType.Length != 0) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(CredType);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -718,6 +767,7 @@
if (other.CredType.Length != 0) {
CredType = other.CredType;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -726,7 +776,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 8: {
UseTestCa = input.ReadBool();
@@ -748,6 +798,7 @@
public sealed partial class ChannelArg : pb::IMessage<ChannelArg> {
private static readonly pb::MessageParser<ChannelArg> _parser = new pb::MessageParser<ChannelArg>(() => new ChannelArg());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<ChannelArg> Parser { get { return _parser; } }
@@ -780,6 +831,7 @@
break;
}
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -856,7 +908,7 @@
if (StrValue != other.StrValue) return false;
if (IntValue != other.IntValue) return false;
if (ValueCase != other.ValueCase) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -866,6 +918,9 @@
if (valueCase_ == ValueOneofCase.StrValue) hash ^= StrValue.GetHashCode();
if (valueCase_ == ValueOneofCase.IntValue) hash ^= IntValue.GetHashCode();
hash ^= (int) valueCase_;
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -888,6 +943,9 @@
output.WriteRawTag(24);
output.WriteInt32(IntValue);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -902,6 +960,9 @@
if (valueCase_ == ValueOneofCase.IntValue) {
size += 1 + pb::CodedOutputStream.ComputeInt32Size(IntValue);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -922,6 +983,7 @@
break;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -930,7 +992,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
Name = input.ReadString();
@@ -952,6 +1014,7 @@
public sealed partial class ClientConfig : pb::IMessage<ClientConfig> {
private static readonly pb::MessageParser<ClientConfig> _parser = new pb::MessageParser<ClientConfig>(() => new ClientConfig());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<ClientConfig> Parser { get { return _parser; } }
@@ -991,6 +1054,7 @@
threadsPerCq_ = other.threadsPerCq_;
messagesPerStream_ = other.messagesPerStream_;
useCoalesceApi_ = other.useCoalesceApi_;
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1244,7 +1308,7 @@
if (ThreadsPerCq != other.ThreadsPerCq) return false;
if (MessagesPerStream != other.MessagesPerStream) return false;
if (UseCoalesceApi != other.UseCoalesceApi) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1267,6 +1331,9 @@
if (ThreadsPerCq != 0) hash ^= ThreadsPerCq.GetHashCode();
if (MessagesPerStream != 0) hash ^= MessagesPerStream.GetHashCode();
if (UseCoalesceApi != false) hash ^= UseCoalesceApi.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -1336,6 +1403,9 @@
output.WriteRawTag(152, 1);
output.WriteBool(UseCoalesceApi);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1386,6 +1456,9 @@
if (UseCoalesceApi != false) {
size += 2 + 1;
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -1451,6 +1524,7 @@
if (other.UseCoalesceApi != false) {
UseCoalesceApi = other.UseCoalesceApi;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1459,7 +1533,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
serverTargets_.AddEntriesFrom(input, _repeated_serverTargets_codec);
@@ -1550,6 +1624,7 @@
public sealed partial class ClientStatus : pb::IMessage<ClientStatus> {
private static readonly pb::MessageParser<ClientStatus> _parser = new pb::MessageParser<ClientStatus>(() => new ClientStatus());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<ClientStatus> Parser { get { return _parser; } }
@@ -1573,6 +1648,7 @@
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ClientStatus(ClientStatus other) : this() {
Stats = other.stats_ != null ? other.Stats.Clone() : null;
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1605,13 +1681,16 @@
return true;
}
if (!object.Equals(Stats, other.Stats)) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (stats_ != null) hash ^= Stats.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -1626,6 +1705,9 @@
output.WriteRawTag(10);
output.WriteMessage(Stats);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1634,6 +1716,9 @@
if (stats_ != null) {
size += 1 + pb::CodedOutputStream.ComputeMessageSize(Stats);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -1648,6 +1733,7 @@
}
Stats.MergeFrom(other.Stats);
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1656,7 +1742,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
if (stats_ == null) {
@@ -1676,6 +1762,7 @@
/// </summary>
public sealed partial class Mark : pb::IMessage<Mark> {
private static readonly pb::MessageParser<Mark> _parser = new pb::MessageParser<Mark>(() => new Mark());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<Mark> Parser { get { return _parser; } }
@@ -1699,6 +1786,7 @@
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Mark(Mark other) : this() {
reset_ = other.reset_;
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1734,13 +1822,16 @@
return true;
}
if (Reset != other.Reset) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Reset != false) hash ^= Reset.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -1755,6 +1846,9 @@
output.WriteRawTag(8);
output.WriteBool(Reset);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1763,6 +1857,9 @@
if (Reset != false) {
size += 1 + 1;
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -1774,6 +1871,7 @@
if (other.Reset != false) {
Reset = other.Reset;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1782,7 +1880,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 8: {
Reset = input.ReadBool();
@@ -1796,6 +1894,7 @@
public sealed partial class ClientArgs : pb::IMessage<ClientArgs> {
private static readonly pb::MessageParser<ClientArgs> _parser = new pb::MessageParser<ClientArgs>(() => new ClientArgs());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<ClientArgs> Parser { get { return _parser; } }
@@ -1827,6 +1926,7 @@
break;
}
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1891,7 +1991,7 @@
if (!object.Equals(Setup, other.Setup)) return false;
if (!object.Equals(Mark, other.Mark)) return false;
if (ArgtypeCase != other.ArgtypeCase) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1900,6 +2000,9 @@
if (argtypeCase_ == ArgtypeOneofCase.Setup) hash ^= Setup.GetHashCode();
if (argtypeCase_ == ArgtypeOneofCase.Mark) hash ^= Mark.GetHashCode();
hash ^= (int) argtypeCase_;
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -1918,6 +2021,9 @@
output.WriteRawTag(18);
output.WriteMessage(Mark);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1929,6 +2035,9 @@
if (argtypeCase_ == ArgtypeOneofCase.Mark) {
size += 1 + pb::CodedOutputStream.ComputeMessageSize(Mark);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -1952,6 +2061,7 @@
break;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1960,7 +2070,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
global::Grpc.Testing.ClientConfig subBuilder = new global::Grpc.Testing.ClientConfig();
@@ -1988,6 +2098,7 @@
public sealed partial class ServerConfig : pb::IMessage<ServerConfig> {
private static readonly pb::MessageParser<ServerConfig> _parser = new pb::MessageParser<ServerConfig>(() => new ServerConfig());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<ServerConfig> Parser { get { return _parser; } }
@@ -2021,6 +2132,7 @@
threadsPerCq_ = other.threadsPerCq_;
resourceQuotaSize_ = other.resourceQuotaSize_;
channelArgs_ = other.channelArgs_.Clone();
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -2198,7 +2310,7 @@
if (ThreadsPerCq != other.ThreadsPerCq) return false;
if (ResourceQuotaSize != other.ResourceQuotaSize) return false;
if(!channelArgs_.Equals(other.channelArgs_)) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -2215,6 +2327,9 @@
if (ThreadsPerCq != 0) hash ^= ThreadsPerCq.GetHashCode();
if (ResourceQuotaSize != 0) hash ^= ResourceQuotaSize.GetHashCode();
hash ^= channelArgs_.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -2263,6 +2378,9 @@
output.WriteInt32(ResourceQuotaSize);
}
channelArgs_.WriteTo(output, _repeated_channelArgs_codec);
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -2297,6 +2415,9 @@
size += 2 + pb::CodedOutputStream.ComputeInt32Size(ResourceQuotaSize);
}
size += channelArgs_.CalculateSize(_repeated_channelArgs_codec);
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -2340,6 +2461,7 @@
ResourceQuotaSize = other.ResourceQuotaSize;
}
channelArgs_.Add(other.channelArgs_);
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -2348,7 +2470,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 8: {
serverType_ = (global::Grpc.Testing.ServerType) input.ReadEnum();
@@ -2409,6 +2531,7 @@
public sealed partial class ServerArgs : pb::IMessage<ServerArgs> {
private static readonly pb::MessageParser<ServerArgs> _parser = new pb::MessageParser<ServerArgs>(() => new ServerArgs());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<ServerArgs> Parser { get { return _parser; } }
@@ -2440,6 +2563,7 @@
break;
}
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -2504,7 +2628,7 @@
if (!object.Equals(Setup, other.Setup)) return false;
if (!object.Equals(Mark, other.Mark)) return false;
if (ArgtypeCase != other.ArgtypeCase) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -2513,6 +2637,9 @@
if (argtypeCase_ == ArgtypeOneofCase.Setup) hash ^= Setup.GetHashCode();
if (argtypeCase_ == ArgtypeOneofCase.Mark) hash ^= Mark.GetHashCode();
hash ^= (int) argtypeCase_;
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -2531,6 +2658,9 @@
output.WriteRawTag(18);
output.WriteMessage(Mark);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -2542,6 +2672,9 @@
if (argtypeCase_ == ArgtypeOneofCase.Mark) {
size += 1 + pb::CodedOutputStream.ComputeMessageSize(Mark);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -2565,6 +2698,7 @@
break;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -2573,7 +2707,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
global::Grpc.Testing.ServerConfig subBuilder = new global::Grpc.Testing.ServerConfig();
@@ -2601,6 +2735,7 @@
public sealed partial class ServerStatus : pb::IMessage<ServerStatus> {
private static readonly pb::MessageParser<ServerStatus> _parser = new pb::MessageParser<ServerStatus>(() => new ServerStatus());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<ServerStatus> Parser { get { return _parser; } }
@@ -2626,6 +2761,7 @@
Stats = other.stats_ != null ? other.Stats.Clone() : null;
port_ = other.port_;
cores_ = other.cores_;
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -2688,7 +2824,7 @@
if (!object.Equals(Stats, other.Stats)) return false;
if (Port != other.Port) return false;
if (Cores != other.Cores) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -2697,6 +2833,9 @@
if (stats_ != null) hash ^= Stats.GetHashCode();
if (Port != 0) hash ^= Port.GetHashCode();
if (Cores != 0) hash ^= Cores.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -2719,6 +2858,9 @@
output.WriteRawTag(24);
output.WriteInt32(Cores);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -2733,6 +2875,9 @@
if (Cores != 0) {
size += 1 + pb::CodedOutputStream.ComputeInt32Size(Cores);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -2753,6 +2898,7 @@
if (other.Cores != 0) {
Cores = other.Cores;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -2761,7 +2907,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
if (stats_ == null) {
@@ -2786,6 +2932,7 @@
public sealed partial class CoreRequest : pb::IMessage<CoreRequest> {
private static readonly pb::MessageParser<CoreRequest> _parser = new pb::MessageParser<CoreRequest>(() => new CoreRequest());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<CoreRequest> Parser { get { return _parser; } }
@@ -2808,6 +2955,7 @@
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public CoreRequest(CoreRequest other) : this() {
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -2828,12 +2976,15 @@
if (ReferenceEquals(other, this)) {
return true;
}
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -2844,11 +2995,17 @@
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -2857,6 +3014,7 @@
if (other == null) {
return;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -2865,7 +3023,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
}
}
@@ -2875,6 +3033,7 @@
public sealed partial class CoreResponse : pb::IMessage<CoreResponse> {
private static readonly pb::MessageParser<CoreResponse> _parser = new pb::MessageParser<CoreResponse>(() => new CoreResponse());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<CoreResponse> Parser { get { return _parser; } }
@@ -2898,6 +3057,7 @@
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public CoreResponse(CoreResponse other) : this() {
cores_ = other.cores_;
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -2933,13 +3093,16 @@
return true;
}
if (Cores != other.Cores) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Cores != 0) hash ^= Cores.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -2954,6 +3117,9 @@
output.WriteRawTag(8);
output.WriteInt32(Cores);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -2962,6 +3128,9 @@
if (Cores != 0) {
size += 1 + pb::CodedOutputStream.ComputeInt32Size(Cores);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -2973,6 +3142,7 @@
if (other.Cores != 0) {
Cores = other.Cores;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -2981,7 +3151,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 8: {
Cores = input.ReadInt32();
@@ -2995,6 +3165,7 @@
public sealed partial class Void : pb::IMessage<Void> {
private static readonly pb::MessageParser<Void> _parser = new pb::MessageParser<Void>(() => new Void());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<Void> Parser { get { return _parser; } }
@@ -3017,6 +3188,7 @@
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Void(Void other) : this() {
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -3037,12 +3209,15 @@
if (ReferenceEquals(other, this)) {
return true;
}
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -3053,11 +3228,17 @@
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -3066,6 +3247,7 @@
if (other == null) {
return;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -3074,7 +3256,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
}
}
@@ -3087,6 +3269,7 @@
/// </summary>
public sealed partial class Scenario : pb::IMessage<Scenario> {
private static readonly pb::MessageParser<Scenario> _parser = new pb::MessageParser<Scenario>(() => new Scenario());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<Scenario> Parser { get { return _parser; } }
@@ -3117,6 +3300,7 @@
warmupSeconds_ = other.warmupSeconds_;
benchmarkSeconds_ = other.benchmarkSeconds_;
spawnLocalWorkerCount_ = other.spawnLocalWorkerCount_;
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -3257,7 +3441,7 @@
if (WarmupSeconds != other.WarmupSeconds) return false;
if (BenchmarkSeconds != other.BenchmarkSeconds) return false;
if (SpawnLocalWorkerCount != other.SpawnLocalWorkerCount) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -3271,6 +3455,9 @@
if (WarmupSeconds != 0) hash ^= WarmupSeconds.GetHashCode();
if (BenchmarkSeconds != 0) hash ^= BenchmarkSeconds.GetHashCode();
if (SpawnLocalWorkerCount != 0) hash ^= SpawnLocalWorkerCount.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -3313,6 +3500,9 @@
output.WriteRawTag(64);
output.WriteInt32(SpawnLocalWorkerCount);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -3342,6 +3532,9 @@
if (SpawnLocalWorkerCount != 0) {
size += 1 + pb::CodedOutputStream.ComputeInt32Size(SpawnLocalWorkerCount);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -3380,6 +3573,7 @@
if (other.SpawnLocalWorkerCount != 0) {
SpawnLocalWorkerCount = other.SpawnLocalWorkerCount;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -3388,7 +3582,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
Name = input.ReadString();
@@ -3439,6 +3633,7 @@
/// </summary>
public sealed partial class Scenarios : pb::IMessage<Scenarios> {
private static readonly pb::MessageParser<Scenarios> _parser = new pb::MessageParser<Scenarios>(() => new Scenarios());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<Scenarios> Parser { get { return _parser; } }
@@ -3462,6 +3657,7 @@
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Scenarios(Scenarios other) : this() {
scenarios_ = other.scenarios_.Clone();
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -3493,13 +3689,16 @@
return true;
}
if(!scenarios_.Equals(other.scenarios_)) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
hash ^= scenarios_.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -3511,12 +3710,18 @@
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
scenarios_.WriteTo(output, _repeated_scenarios_codec);
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
size += scenarios_.CalculateSize(_repeated_scenarios_codec);
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -3526,6 +3731,7 @@
return;
}
scenarios_.Add(other.scenarios_);
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -3534,7 +3740,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
scenarios_.AddEntriesFrom(input, _repeated_scenarios_codec);
@@ -3552,6 +3758,7 @@
/// </summary>
public sealed partial class ScenarioResultSummary : pb::IMessage<ScenarioResultSummary> {
private static readonly pb::MessageParser<ScenarioResultSummary> _parser = new pb::MessageParser<ScenarioResultSummary>(() => new ScenarioResultSummary());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<ScenarioResultSummary> Parser { get { return _parser; } }
@@ -3592,6 +3799,7 @@
serverPollsPerRequest_ = other.serverPollsPerRequest_;
serverQueriesPerCpuSec_ = other.serverQueriesPerCpuSec_;
clientQueriesPerCpuSec_ = other.clientQueriesPerCpuSec_;
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -3843,48 +4051,51 @@
if (ReferenceEquals(other, this)) {
return true;
}
- if (Qps != other.Qps) return false;
- if (QpsPerServerCore != other.QpsPerServerCore) return false;
- if (ServerSystemTime != other.ServerSystemTime) return false;
- if (ServerUserTime != other.ServerUserTime) return false;
- if (ClientSystemTime != other.ClientSystemTime) return false;
- if (ClientUserTime != other.ClientUserTime) return false;
- if (Latency50 != other.Latency50) return false;
- if (Latency90 != other.Latency90) return false;
- if (Latency95 != other.Latency95) return false;
- if (Latency99 != other.Latency99) return false;
- if (Latency999 != other.Latency999) return false;
- if (ServerCpuUsage != other.ServerCpuUsage) return false;
- if (SuccessfulRequestsPerSecond != other.SuccessfulRequestsPerSecond) return false;
- if (FailedRequestsPerSecond != other.FailedRequestsPerSecond) return false;
- if (ClientPollsPerRequest != other.ClientPollsPerRequest) return false;
- if (ServerPollsPerRequest != other.ServerPollsPerRequest) return false;
- if (ServerQueriesPerCpuSec != other.ServerQueriesPerCpuSec) return false;
- if (ClientQueriesPerCpuSec != other.ClientQueriesPerCpuSec) return false;
- return true;
+ if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(Qps, other.Qps)) return false;
+ if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(QpsPerServerCore, other.QpsPerServerCore)) return false;
+ if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(ServerSystemTime, other.ServerSystemTime)) return false;
+ if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(ServerUserTime, other.ServerUserTime)) return false;
+ if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(ClientSystemTime, other.ClientSystemTime)) return false;
+ if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(ClientUserTime, other.ClientUserTime)) return false;
+ if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(Latency50, other.Latency50)) return false;
+ if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(Latency90, other.Latency90)) return false;
+ if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(Latency95, other.Latency95)) return false;
+ if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(Latency99, other.Latency99)) return false;
+ if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(Latency999, other.Latency999)) return false;
+ if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(ServerCpuUsage, other.ServerCpuUsage)) return false;
+ if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(SuccessfulRequestsPerSecond, other.SuccessfulRequestsPerSecond)) return false;
+ if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(FailedRequestsPerSecond, other.FailedRequestsPerSecond)) return false;
+ if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(ClientPollsPerRequest, other.ClientPollsPerRequest)) return false;
+ if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(ServerPollsPerRequest, other.ServerPollsPerRequest)) return false;
+ if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(ServerQueriesPerCpuSec, other.ServerQueriesPerCpuSec)) return false;
+ if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(ClientQueriesPerCpuSec, other.ClientQueriesPerCpuSec)) return false;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
- if (Qps != 0D) hash ^= Qps.GetHashCode();
- if (QpsPerServerCore != 0D) hash ^= QpsPerServerCore.GetHashCode();
- if (ServerSystemTime != 0D) hash ^= ServerSystemTime.GetHashCode();
- if (ServerUserTime != 0D) hash ^= ServerUserTime.GetHashCode();
- if (ClientSystemTime != 0D) hash ^= ClientSystemTime.GetHashCode();
- if (ClientUserTime != 0D) hash ^= ClientUserTime.GetHashCode();
- if (Latency50 != 0D) hash ^= Latency50.GetHashCode();
- if (Latency90 != 0D) hash ^= Latency90.GetHashCode();
- if (Latency95 != 0D) hash ^= Latency95.GetHashCode();
- if (Latency99 != 0D) hash ^= Latency99.GetHashCode();
- if (Latency999 != 0D) hash ^= Latency999.GetHashCode();
- if (ServerCpuUsage != 0D) hash ^= ServerCpuUsage.GetHashCode();
- if (SuccessfulRequestsPerSecond != 0D) hash ^= SuccessfulRequestsPerSecond.GetHashCode();
- if (FailedRequestsPerSecond != 0D) hash ^= FailedRequestsPerSecond.GetHashCode();
- if (ClientPollsPerRequest != 0D) hash ^= ClientPollsPerRequest.GetHashCode();
- if (ServerPollsPerRequest != 0D) hash ^= ServerPollsPerRequest.GetHashCode();
- if (ServerQueriesPerCpuSec != 0D) hash ^= ServerQueriesPerCpuSec.GetHashCode();
- if (ClientQueriesPerCpuSec != 0D) hash ^= ClientQueriesPerCpuSec.GetHashCode();
+ if (Qps != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(Qps);
+ if (QpsPerServerCore != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(QpsPerServerCore);
+ if (ServerSystemTime != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(ServerSystemTime);
+ if (ServerUserTime != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(ServerUserTime);
+ if (ClientSystemTime != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(ClientSystemTime);
+ if (ClientUserTime != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(ClientUserTime);
+ if (Latency50 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(Latency50);
+ if (Latency90 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(Latency90);
+ if (Latency95 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(Latency95);
+ if (Latency99 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(Latency99);
+ if (Latency999 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(Latency999);
+ if (ServerCpuUsage != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(ServerCpuUsage);
+ if (SuccessfulRequestsPerSecond != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(SuccessfulRequestsPerSecond);
+ if (FailedRequestsPerSecond != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(FailedRequestsPerSecond);
+ if (ClientPollsPerRequest != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(ClientPollsPerRequest);
+ if (ServerPollsPerRequest != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(ServerPollsPerRequest);
+ if (ServerQueriesPerCpuSec != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(ServerQueriesPerCpuSec);
+ if (ClientQueriesPerCpuSec != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(ClientQueriesPerCpuSec);
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -3967,6 +4178,9 @@
output.WriteRawTag(145, 1);
output.WriteDouble(ClientQueriesPerCpuSec);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -4026,6 +4240,9 @@
if (ClientQueriesPerCpuSec != 0D) {
size += 2 + 8;
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -4088,6 +4305,7 @@
if (other.ClientQueriesPerCpuSec != 0D) {
ClientQueriesPerCpuSec = other.ClientQueriesPerCpuSec;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -4096,7 +4314,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 9: {
Qps = input.ReadDouble();
@@ -4181,6 +4399,7 @@
/// </summary>
public sealed partial class ScenarioResult : pb::IMessage<ScenarioResult> {
private static readonly pb::MessageParser<ScenarioResult> _parser = new pb::MessageParser<ScenarioResult>(() => new ScenarioResult());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<ScenarioResult> Parser { get { return _parser; } }
@@ -4212,6 +4431,7 @@
clientSuccess_ = other.clientSuccess_.Clone();
serverSuccess_ = other.serverSuccess_.Clone();
requestResults_ = other.requestResults_.Clone();
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -4358,7 +4578,7 @@
if(!clientSuccess_.Equals(other.clientSuccess_)) return false;
if(!serverSuccess_.Equals(other.serverSuccess_)) return false;
if(!requestResults_.Equals(other.requestResults_)) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -4373,6 +4593,9 @@
hash ^= clientSuccess_.GetHashCode();
hash ^= serverSuccess_.GetHashCode();
hash ^= requestResults_.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -4401,6 +4624,9 @@
clientSuccess_.WriteTo(output, _repeated_clientSuccess_codec);
serverSuccess_.WriteTo(output, _repeated_serverSuccess_codec);
requestResults_.WriteTo(output, _repeated_requestResults_codec);
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -4421,6 +4647,9 @@
size += clientSuccess_.CalculateSize(_repeated_clientSuccess_codec);
size += serverSuccess_.CalculateSize(_repeated_serverSuccess_codec);
size += requestResults_.CalculateSize(_repeated_requestResults_codec);
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -4453,6 +4682,7 @@
clientSuccess_.Add(other.clientSuccess_);
serverSuccess_.Add(other.serverSuccess_);
requestResults_.Add(other.requestResults_);
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -4461,7 +4691,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
if (scenario_ == null) {
diff --git a/src/csharp/Grpc.IntegrationTesting/CoreStats/Stats.cs b/src/csharp/Grpc.IntegrationTesting/CoreStats/Stats.cs
index 380294e..4ff56cd 100644
--- a/src/csharp/Grpc.IntegrationTesting/CoreStats/Stats.cs
+++ b/src/csharp/Grpc.IntegrationTesting/CoreStats/Stats.cs
@@ -1,5 +1,7 @@
-// Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: grpc/core/stats.proto
+// <auto-generated>
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: grpc/core/stats.proto
+// </auto-generated>
#pragma warning disable 1591, 0612, 3021
#region Designer generated code
@@ -43,6 +45,7 @@
#region Messages
public sealed partial class Bucket : pb::IMessage<Bucket> {
private static readonly pb::MessageParser<Bucket> _parser = new pb::MessageParser<Bucket>(() => new Bucket());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<Bucket> Parser { get { return _parser; } }
@@ -67,6 +70,7 @@
public Bucket(Bucket other) : this() {
start_ = other.start_;
count_ = other.count_;
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -109,16 +113,19 @@
if (ReferenceEquals(other, this)) {
return true;
}
- if (Start != other.Start) return false;
+ if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(Start, other.Start)) return false;
if (Count != other.Count) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
- if (Start != 0D) hash ^= Start.GetHashCode();
+ if (Start != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(Start);
if (Count != 0UL) hash ^= Count.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -137,6 +144,9 @@
output.WriteRawTag(16);
output.WriteUInt64(Count);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -148,6 +158,9 @@
if (Count != 0UL) {
size += 1 + pb::CodedOutputStream.ComputeUInt64Size(Count);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -162,6 +175,7 @@
if (other.Count != 0UL) {
Count = other.Count;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -170,7 +184,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 9: {
Start = input.ReadDouble();
@@ -188,6 +202,7 @@
public sealed partial class Histogram : pb::IMessage<Histogram> {
private static readonly pb::MessageParser<Histogram> _parser = new pb::MessageParser<Histogram>(() => new Histogram());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<Histogram> Parser { get { return _parser; } }
@@ -211,6 +226,7 @@
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Histogram(Histogram other) : this() {
buckets_ = other.buckets_.Clone();
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -242,13 +258,16 @@
return true;
}
if(!buckets_.Equals(other.buckets_)) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
hash ^= buckets_.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -260,12 +279,18 @@
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
buckets_.WriteTo(output, _repeated_buckets_codec);
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
size += buckets_.CalculateSize(_repeated_buckets_codec);
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -275,6 +300,7 @@
return;
}
buckets_.Add(other.buckets_);
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -283,7 +309,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
buckets_.AddEntriesFrom(input, _repeated_buckets_codec);
@@ -297,6 +323,7 @@
public sealed partial class Metric : pb::IMessage<Metric> {
private static readonly pb::MessageParser<Metric> _parser = new pb::MessageParser<Metric>(() => new Metric());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<Metric> Parser { get { return _parser; } }
@@ -329,6 +356,7 @@
break;
}
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -405,7 +433,7 @@
if (Count != other.Count) return false;
if (!object.Equals(Histogram, other.Histogram)) return false;
if (ValueCase != other.ValueCase) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -415,6 +443,9 @@
if (valueCase_ == ValueOneofCase.Count) hash ^= Count.GetHashCode();
if (valueCase_ == ValueOneofCase.Histogram) hash ^= Histogram.GetHashCode();
hash ^= (int) valueCase_;
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -437,6 +468,9 @@
output.WriteRawTag(90);
output.WriteMessage(Histogram);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -451,6 +485,9 @@
if (valueCase_ == ValueOneofCase.Histogram) {
size += 1 + pb::CodedOutputStream.ComputeMessageSize(Histogram);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -474,6 +511,7 @@
break;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -482,7 +520,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
Name = input.ReadString();
@@ -509,6 +547,7 @@
public sealed partial class Stats : pb::IMessage<Stats> {
private static readonly pb::MessageParser<Stats> _parser = new pb::MessageParser<Stats>(() => new Stats());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<Stats> Parser { get { return _parser; } }
@@ -532,6 +571,7 @@
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Stats(Stats other) : this() {
metrics_ = other.metrics_.Clone();
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -563,13 +603,16 @@
return true;
}
if(!metrics_.Equals(other.metrics_)) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
hash ^= metrics_.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -581,12 +624,18 @@
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
metrics_.WriteTo(output, _repeated_metrics_codec);
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
size += metrics_.CalculateSize(_repeated_metrics_codec);
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -596,6 +645,7 @@
return;
}
metrics_.Add(other.metrics_);
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -604,7 +654,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
metrics_.AddEntriesFrom(input, _repeated_metrics_codec);
diff --git a/src/csharp/Grpc.IntegrationTesting/EchoMessages.cs b/src/csharp/Grpc.IntegrationTesting/EchoMessages.cs
index 9581ade..39c3d76 100644
--- a/src/csharp/Grpc.IntegrationTesting/EchoMessages.cs
+++ b/src/csharp/Grpc.IntegrationTesting/EchoMessages.cs
@@ -1,5 +1,7 @@
-// Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: src/proto/grpc/testing/echo_messages.proto
+// <auto-generated>
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: src/proto/grpc/testing/echo_messages.proto
+// </auto-generated>
#pragma warning disable 1591, 0612, 3021
#region Designer generated code
@@ -63,6 +65,7 @@
/// </summary>
public sealed partial class DebugInfo : pb::IMessage<DebugInfo> {
private static readonly pb::MessageParser<DebugInfo> _parser = new pb::MessageParser<DebugInfo>(() => new DebugInfo());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<DebugInfo> Parser { get { return _parser; } }
@@ -87,6 +90,7 @@
public DebugInfo(DebugInfo other) : this() {
stackEntries_ = other.stackEntries_.Clone();
detail_ = other.detail_;
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -130,7 +134,7 @@
}
if(!stackEntries_.Equals(other.stackEntries_)) return false;
if (Detail != other.Detail) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -138,6 +142,9 @@
int hash = 1;
hash ^= stackEntries_.GetHashCode();
if (Detail.Length != 0) hash ^= Detail.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -153,6 +160,9 @@
output.WriteRawTag(18);
output.WriteString(Detail);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -162,6 +172,9 @@
if (Detail.Length != 0) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(Detail);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -174,6 +187,7 @@
if (other.Detail.Length != 0) {
Detail = other.Detail;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -182,7 +196,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
stackEntries_.AddEntriesFrom(input, _repeated_stackEntries_codec);
@@ -203,6 +217,7 @@
/// </summary>
public sealed partial class ErrorStatus : pb::IMessage<ErrorStatus> {
private static readonly pb::MessageParser<ErrorStatus> _parser = new pb::MessageParser<ErrorStatus>(() => new ErrorStatus());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<ErrorStatus> Parser { get { return _parser; } }
@@ -228,6 +243,7 @@
code_ = other.code_;
errorMessage_ = other.errorMessage_;
binaryErrorDetails_ = other.binaryErrorDetails_;
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -284,7 +300,7 @@
if (Code != other.Code) return false;
if (ErrorMessage != other.ErrorMessage) return false;
if (BinaryErrorDetails != other.BinaryErrorDetails) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -293,6 +309,9 @@
if (Code != 0) hash ^= Code.GetHashCode();
if (ErrorMessage.Length != 0) hash ^= ErrorMessage.GetHashCode();
if (BinaryErrorDetails.Length != 0) hash ^= BinaryErrorDetails.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -315,6 +334,9 @@
output.WriteRawTag(26);
output.WriteString(BinaryErrorDetails);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -329,6 +351,9 @@
if (BinaryErrorDetails.Length != 0) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(BinaryErrorDetails);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -346,6 +371,7 @@
if (other.BinaryErrorDetails.Length != 0) {
BinaryErrorDetails = other.BinaryErrorDetails;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -354,7 +380,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 8: {
Code = input.ReadInt32();
@@ -376,6 +402,7 @@
public sealed partial class RequestParams : pb::IMessage<RequestParams> {
private static readonly pb::MessageParser<RequestParams> _parser = new pb::MessageParser<RequestParams>(() => new RequestParams());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<RequestParams> Parser { get { return _parser; } }
@@ -413,6 +440,7 @@
binaryErrorDetails_ = other.binaryErrorDetails_;
ExpectedError = other.expectedError_ != null ? other.ExpectedError.Clone() : null;
serverSleepUs_ = other.serverSleepUs_;
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -622,7 +650,7 @@
if (BinaryErrorDetails != other.BinaryErrorDetails) return false;
if (!object.Equals(ExpectedError, other.ExpectedError)) return false;
if (ServerSleepUs != other.ServerSleepUs) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -643,6 +671,9 @@
if (BinaryErrorDetails.Length != 0) hash ^= BinaryErrorDetails.GetHashCode();
if (expectedError_ != null) hash ^= ExpectedError.GetHashCode();
if (ServerSleepUs != 0) hash ^= ServerSleepUs.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -713,6 +744,9 @@
output.WriteRawTag(120);
output.WriteInt32(ServerSleepUs);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -763,6 +797,9 @@
if (ServerSleepUs != 0) {
size += 1 + pb::CodedOutputStream.ComputeInt32Size(ServerSleepUs);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -822,6 +859,7 @@
if (other.ServerSleepUs != 0) {
ServerSleepUs = other.ServerSleepUs;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -830,7 +868,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 8: {
EchoDeadline = input.ReadBool();
@@ -906,6 +944,7 @@
public sealed partial class EchoRequest : pb::IMessage<EchoRequest> {
private static readonly pb::MessageParser<EchoRequest> _parser = new pb::MessageParser<EchoRequest>(() => new EchoRequest());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<EchoRequest> Parser { get { return _parser; } }
@@ -930,6 +969,7 @@
public EchoRequest(EchoRequest other) : this() {
message_ = other.message_;
Param = other.param_ != null ? other.Param.Clone() : null;
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -974,7 +1014,7 @@
}
if (Message != other.Message) return false;
if (!object.Equals(Param, other.Param)) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -982,6 +1022,9 @@
int hash = 1;
if (Message.Length != 0) hash ^= Message.GetHashCode();
if (param_ != null) hash ^= Param.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -1000,6 +1043,9 @@
output.WriteRawTag(18);
output.WriteMessage(Param);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1011,6 +1057,9 @@
if (param_ != null) {
size += 1 + pb::CodedOutputStream.ComputeMessageSize(Param);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -1028,6 +1077,7 @@
}
Param.MergeFrom(other.Param);
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1036,7 +1086,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
Message = input.ReadString();
@@ -1057,6 +1107,7 @@
public sealed partial class ResponseParams : pb::IMessage<ResponseParams> {
private static readonly pb::MessageParser<ResponseParams> _parser = new pb::MessageParser<ResponseParams>(() => new ResponseParams());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<ResponseParams> Parser { get { return _parser; } }
@@ -1082,6 +1133,7 @@
requestDeadline_ = other.requestDeadline_;
host_ = other.host_;
peer_ = other.peer_;
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1138,7 +1190,7 @@
if (RequestDeadline != other.RequestDeadline) return false;
if (Host != other.Host) return false;
if (Peer != other.Peer) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1147,6 +1199,9 @@
if (RequestDeadline != 0L) hash ^= RequestDeadline.GetHashCode();
if (Host.Length != 0) hash ^= Host.GetHashCode();
if (Peer.Length != 0) hash ^= Peer.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -1169,6 +1224,9 @@
output.WriteRawTag(26);
output.WriteString(Peer);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1183,6 +1241,9 @@
if (Peer.Length != 0) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(Peer);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -1200,6 +1261,7 @@
if (other.Peer.Length != 0) {
Peer = other.Peer;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1208,7 +1270,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 8: {
RequestDeadline = input.ReadInt64();
@@ -1230,6 +1292,7 @@
public sealed partial class EchoResponse : pb::IMessage<EchoResponse> {
private static readonly pb::MessageParser<EchoResponse> _parser = new pb::MessageParser<EchoResponse>(() => new EchoResponse());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<EchoResponse> Parser { get { return _parser; } }
@@ -1254,6 +1317,7 @@
public EchoResponse(EchoResponse other) : this() {
message_ = other.message_;
Param = other.param_ != null ? other.Param.Clone() : null;
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1298,7 +1362,7 @@
}
if (Message != other.Message) return false;
if (!object.Equals(Param, other.Param)) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1306,6 +1370,9 @@
int hash = 1;
if (Message.Length != 0) hash ^= Message.GetHashCode();
if (param_ != null) hash ^= Param.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -1324,6 +1391,9 @@
output.WriteRawTag(18);
output.WriteMessage(Param);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1335,6 +1405,9 @@
if (param_ != null) {
size += 1 + pb::CodedOutputStream.ComputeMessageSize(Param);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -1352,6 +1425,7 @@
}
Param.MergeFrom(other.Param);
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1360,7 +1434,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
Message = input.ReadString();
diff --git a/src/csharp/Grpc.IntegrationTesting/Empty.cs b/src/csharp/Grpc.IntegrationTesting/Empty.cs
index 24ffd61..0d4c28b 100644
--- a/src/csharp/Grpc.IntegrationTesting/Empty.cs
+++ b/src/csharp/Grpc.IntegrationTesting/Empty.cs
@@ -1,5 +1,7 @@
-// Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: src/proto/grpc/testing/empty.proto
+// <auto-generated>
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: src/proto/grpc/testing/empty.proto
+// </auto-generated>
#pragma warning disable 1591, 0612, 3021
#region Designer generated code
@@ -45,6 +47,7 @@
/// </summary>
public sealed partial class Empty : pb::IMessage<Empty> {
private static readonly pb::MessageParser<Empty> _parser = new pb::MessageParser<Empty>(() => new Empty());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<Empty> Parser { get { return _parser; } }
@@ -67,6 +70,7 @@
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Empty(Empty other) : this() {
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -87,12 +91,15 @@
if (ReferenceEquals(other, this)) {
return true;
}
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -103,11 +110,17 @@
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -116,6 +129,7 @@
if (other == null) {
return;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -124,7 +138,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
}
}
diff --git a/src/csharp/Grpc.IntegrationTesting/Messages.cs b/src/csharp/Grpc.IntegrationTesting/Messages.cs
index 278ef66..b5c93ba 100644
--- a/src/csharp/Grpc.IntegrationTesting/Messages.cs
+++ b/src/csharp/Grpc.IntegrationTesting/Messages.cs
@@ -1,5 +1,7 @@
-// Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: src/proto/grpc/testing/messages.proto
+// <auto-generated>
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: src/proto/grpc/testing/messages.proto
+// </auto-generated>
#pragma warning disable 1591, 0612, 3021
#region Designer generated code
@@ -95,6 +97,7 @@
/// </summary>
public sealed partial class BoolValue : pb::IMessage<BoolValue> {
private static readonly pb::MessageParser<BoolValue> _parser = new pb::MessageParser<BoolValue>(() => new BoolValue());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<BoolValue> Parser { get { return _parser; } }
@@ -118,6 +121,7 @@
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public BoolValue(BoolValue other) : this() {
value_ = other.value_;
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -153,13 +157,16 @@
return true;
}
if (Value != other.Value) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Value != false) hash ^= Value.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -174,6 +181,9 @@
output.WriteRawTag(8);
output.WriteBool(Value);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -182,6 +192,9 @@
if (Value != false) {
size += 1 + 1;
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -193,6 +206,7 @@
if (other.Value != false) {
Value = other.Value;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -201,7 +215,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 8: {
Value = input.ReadBool();
@@ -218,6 +232,7 @@
/// </summary>
public sealed partial class Payload : pb::IMessage<Payload> {
private static readonly pb::MessageParser<Payload> _parser = new pb::MessageParser<Payload>(() => new Payload());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<Payload> Parser { get { return _parser; } }
@@ -242,6 +257,7 @@
public Payload(Payload other) : this() {
type_ = other.type_;
body_ = other.body_;
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -293,7 +309,7 @@
}
if (Type != other.Type) return false;
if (Body != other.Body) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -301,6 +317,9 @@
int hash = 1;
if (Type != 0) hash ^= Type.GetHashCode();
if (Body.Length != 0) hash ^= Body.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -319,6 +338,9 @@
output.WriteRawTag(18);
output.WriteBytes(Body);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -330,6 +352,9 @@
if (Body.Length != 0) {
size += 1 + pb::CodedOutputStream.ComputeBytesSize(Body);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -344,6 +369,7 @@
if (other.Body.Length != 0) {
Body = other.Body;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -352,7 +378,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 8: {
type_ = (global::Grpc.Testing.PayloadType) input.ReadEnum();
@@ -374,6 +400,7 @@
/// </summary>
public sealed partial class EchoStatus : pb::IMessage<EchoStatus> {
private static readonly pb::MessageParser<EchoStatus> _parser = new pb::MessageParser<EchoStatus>(() => new EchoStatus());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<EchoStatus> Parser { get { return _parser; } }
@@ -398,6 +425,7 @@
public EchoStatus(EchoStatus other) : this() {
code_ = other.code_;
message_ = other.message_;
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -442,7 +470,7 @@
}
if (Code != other.Code) return false;
if (Message != other.Message) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -450,6 +478,9 @@
int hash = 1;
if (Code != 0) hash ^= Code.GetHashCode();
if (Message.Length != 0) hash ^= Message.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -468,6 +499,9 @@
output.WriteRawTag(18);
output.WriteString(Message);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -479,6 +513,9 @@
if (Message.Length != 0) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(Message);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -493,6 +530,7 @@
if (other.Message.Length != 0) {
Message = other.Message;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -501,7 +539,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 8: {
Code = input.ReadInt32();
@@ -522,6 +560,7 @@
/// </summary>
public sealed partial class SimpleRequest : pb::IMessage<SimpleRequest> {
private static readonly pb::MessageParser<SimpleRequest> _parser = new pb::MessageParser<SimpleRequest>(() => new SimpleRequest());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<SimpleRequest> Parser { get { return _parser; } }
@@ -552,6 +591,7 @@
ResponseCompressed = other.responseCompressed_ != null ? other.ResponseCompressed.Clone() : null;
ResponseStatus = other.responseStatus_ != null ? other.ResponseStatus.Clone() : null;
ExpectCompressed = other.expectCompressed_ != null ? other.ExpectCompressed.Clone() : null;
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -697,7 +737,7 @@
if (!object.Equals(ResponseCompressed, other.ResponseCompressed)) return false;
if (!object.Equals(ResponseStatus, other.ResponseStatus)) return false;
if (!object.Equals(ExpectCompressed, other.ExpectCompressed)) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -711,6 +751,9 @@
if (responseCompressed_ != null) hash ^= ResponseCompressed.GetHashCode();
if (responseStatus_ != null) hash ^= ResponseStatus.GetHashCode();
if (expectCompressed_ != null) hash ^= ExpectCompressed.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -753,6 +796,9 @@
output.WriteRawTag(66);
output.WriteMessage(ExpectCompressed);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -782,6 +828,9 @@
if (expectCompressed_ != null) {
size += 1 + pb::CodedOutputStream.ComputeMessageSize(ExpectCompressed);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -826,6 +875,7 @@
}
ExpectCompressed.MergeFrom(other.ExpectCompressed);
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -834,7 +884,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 8: {
responseType_ = (global::Grpc.Testing.PayloadType) input.ReadEnum();
@@ -891,6 +941,7 @@
/// </summary>
public sealed partial class SimpleResponse : pb::IMessage<SimpleResponse> {
private static readonly pb::MessageParser<SimpleResponse> _parser = new pb::MessageParser<SimpleResponse>(() => new SimpleResponse());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<SimpleResponse> Parser { get { return _parser; } }
@@ -916,6 +967,7 @@
Payload = other.payload_ != null ? other.Payload.Clone() : null;
username_ = other.username_;
oauthScope_ = other.oauthScope_;
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -982,7 +1034,7 @@
if (!object.Equals(Payload, other.Payload)) return false;
if (Username != other.Username) return false;
if (OauthScope != other.OauthScope) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -991,6 +1043,9 @@
if (payload_ != null) hash ^= Payload.GetHashCode();
if (Username.Length != 0) hash ^= Username.GetHashCode();
if (OauthScope.Length != 0) hash ^= OauthScope.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -1013,6 +1068,9 @@
output.WriteRawTag(26);
output.WriteString(OauthScope);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1027,6 +1085,9 @@
if (OauthScope.Length != 0) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(OauthScope);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -1047,6 +1108,7 @@
if (other.OauthScope.Length != 0) {
OauthScope = other.OauthScope;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1055,7 +1117,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
if (payload_ == null) {
@@ -1083,6 +1145,7 @@
/// </summary>
public sealed partial class StreamingInputCallRequest : pb::IMessage<StreamingInputCallRequest> {
private static readonly pb::MessageParser<StreamingInputCallRequest> _parser = new pb::MessageParser<StreamingInputCallRequest>(() => new StreamingInputCallRequest());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<StreamingInputCallRequest> Parser { get { return _parser; } }
@@ -1107,6 +1170,7 @@
public StreamingInputCallRequest(StreamingInputCallRequest other) : this() {
Payload = other.payload_ != null ? other.Payload.Clone() : null;
ExpectCompressed = other.expectCompressed_ != null ? other.ExpectCompressed.Clone() : null;
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1160,7 +1224,7 @@
}
if (!object.Equals(Payload, other.Payload)) return false;
if (!object.Equals(ExpectCompressed, other.ExpectCompressed)) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1168,6 +1232,9 @@
int hash = 1;
if (payload_ != null) hash ^= Payload.GetHashCode();
if (expectCompressed_ != null) hash ^= ExpectCompressed.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -1186,6 +1253,9 @@
output.WriteRawTag(18);
output.WriteMessage(ExpectCompressed);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1197,6 +1267,9 @@
if (expectCompressed_ != null) {
size += 1 + pb::CodedOutputStream.ComputeMessageSize(ExpectCompressed);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -1217,6 +1290,7 @@
}
ExpectCompressed.MergeFrom(other.ExpectCompressed);
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1225,7 +1299,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
if (payload_ == null) {
@@ -1252,6 +1326,7 @@
/// </summary>
public sealed partial class StreamingInputCallResponse : pb::IMessage<StreamingInputCallResponse> {
private static readonly pb::MessageParser<StreamingInputCallResponse> _parser = new pb::MessageParser<StreamingInputCallResponse>(() => new StreamingInputCallResponse());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<StreamingInputCallResponse> Parser { get { return _parser; } }
@@ -1275,6 +1350,7 @@
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public StreamingInputCallResponse(StreamingInputCallResponse other) : this() {
aggregatedPayloadSize_ = other.aggregatedPayloadSize_;
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1310,13 +1386,16 @@
return true;
}
if (AggregatedPayloadSize != other.AggregatedPayloadSize) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (AggregatedPayloadSize != 0) hash ^= AggregatedPayloadSize.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -1331,6 +1410,9 @@
output.WriteRawTag(8);
output.WriteInt32(AggregatedPayloadSize);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1339,6 +1421,9 @@
if (AggregatedPayloadSize != 0) {
size += 1 + pb::CodedOutputStream.ComputeInt32Size(AggregatedPayloadSize);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -1350,6 +1435,7 @@
if (other.AggregatedPayloadSize != 0) {
AggregatedPayloadSize = other.AggregatedPayloadSize;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1358,7 +1444,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 8: {
AggregatedPayloadSize = input.ReadInt32();
@@ -1375,6 +1461,7 @@
/// </summary>
public sealed partial class ResponseParameters : pb::IMessage<ResponseParameters> {
private static readonly pb::MessageParser<ResponseParameters> _parser = new pb::MessageParser<ResponseParameters>(() => new ResponseParameters());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<ResponseParameters> Parser { get { return _parser; } }
@@ -1400,6 +1487,7 @@
size_ = other.size_;
intervalUs_ = other.intervalUs_;
Compressed = other.compressed_ != null ? other.Compressed.Clone() : null;
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1469,7 +1557,7 @@
if (Size != other.Size) return false;
if (IntervalUs != other.IntervalUs) return false;
if (!object.Equals(Compressed, other.Compressed)) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1478,6 +1566,9 @@
if (Size != 0) hash ^= Size.GetHashCode();
if (IntervalUs != 0) hash ^= IntervalUs.GetHashCode();
if (compressed_ != null) hash ^= Compressed.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -1500,6 +1591,9 @@
output.WriteRawTag(26);
output.WriteMessage(Compressed);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1514,6 +1608,9 @@
if (compressed_ != null) {
size += 1 + pb::CodedOutputStream.ComputeMessageSize(Compressed);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -1534,6 +1631,7 @@
}
Compressed.MergeFrom(other.Compressed);
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1542,7 +1640,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 8: {
Size = input.ReadInt32();
@@ -1570,6 +1668,7 @@
/// </summary>
public sealed partial class StreamingOutputCallRequest : pb::IMessage<StreamingOutputCallRequest> {
private static readonly pb::MessageParser<StreamingOutputCallRequest> _parser = new pb::MessageParser<StreamingOutputCallRequest>(() => new StreamingOutputCallRequest());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<StreamingOutputCallRequest> Parser { get { return _parser; } }
@@ -1596,6 +1695,7 @@
responseParameters_ = other.responseParameters_.Clone();
Payload = other.payload_ != null ? other.Payload.Clone() : null;
ResponseStatus = other.responseStatus_ != null ? other.ResponseStatus.Clone() : null;
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1679,7 +1779,7 @@
if(!responseParameters_.Equals(other.responseParameters_)) return false;
if (!object.Equals(Payload, other.Payload)) return false;
if (!object.Equals(ResponseStatus, other.ResponseStatus)) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1689,6 +1789,9 @@
hash ^= responseParameters_.GetHashCode();
if (payload_ != null) hash ^= Payload.GetHashCode();
if (responseStatus_ != null) hash ^= ResponseStatus.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -1712,6 +1815,9 @@
output.WriteRawTag(58);
output.WriteMessage(ResponseStatus);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1727,6 +1833,9 @@
if (responseStatus_ != null) {
size += 1 + pb::CodedOutputStream.ComputeMessageSize(ResponseStatus);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -1751,6 +1860,7 @@
}
ResponseStatus.MergeFrom(other.ResponseStatus);
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1759,7 +1869,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 8: {
responseType_ = (global::Grpc.Testing.PayloadType) input.ReadEnum();
@@ -1794,6 +1904,7 @@
/// </summary>
public sealed partial class StreamingOutputCallResponse : pb::IMessage<StreamingOutputCallResponse> {
private static readonly pb::MessageParser<StreamingOutputCallResponse> _parser = new pb::MessageParser<StreamingOutputCallResponse>(() => new StreamingOutputCallResponse());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<StreamingOutputCallResponse> Parser { get { return _parser; } }
@@ -1817,6 +1928,7 @@
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public StreamingOutputCallResponse(StreamingOutputCallResponse other) : this() {
Payload = other.payload_ != null ? other.Payload.Clone() : null;
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1852,13 +1964,16 @@
return true;
}
if (!object.Equals(Payload, other.Payload)) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (payload_ != null) hash ^= Payload.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -1873,6 +1988,9 @@
output.WriteRawTag(10);
output.WriteMessage(Payload);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1881,6 +1999,9 @@
if (payload_ != null) {
size += 1 + pb::CodedOutputStream.ComputeMessageSize(Payload);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -1895,6 +2016,7 @@
}
Payload.MergeFrom(other.Payload);
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1903,7 +2025,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
if (payload_ == null) {
@@ -1924,6 +2046,7 @@
/// </summary>
public sealed partial class ReconnectParams : pb::IMessage<ReconnectParams> {
private static readonly pb::MessageParser<ReconnectParams> _parser = new pb::MessageParser<ReconnectParams>(() => new ReconnectParams());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<ReconnectParams> Parser { get { return _parser; } }
@@ -1947,6 +2070,7 @@
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ReconnectParams(ReconnectParams other) : this() {
maxReconnectBackoffMs_ = other.maxReconnectBackoffMs_;
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1979,13 +2103,16 @@
return true;
}
if (MaxReconnectBackoffMs != other.MaxReconnectBackoffMs) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (MaxReconnectBackoffMs != 0) hash ^= MaxReconnectBackoffMs.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -2000,6 +2127,9 @@
output.WriteRawTag(8);
output.WriteInt32(MaxReconnectBackoffMs);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -2008,6 +2138,9 @@
if (MaxReconnectBackoffMs != 0) {
size += 1 + pb::CodedOutputStream.ComputeInt32Size(MaxReconnectBackoffMs);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -2019,6 +2152,7 @@
if (other.MaxReconnectBackoffMs != 0) {
MaxReconnectBackoffMs = other.MaxReconnectBackoffMs;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -2027,7 +2161,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 8: {
MaxReconnectBackoffMs = input.ReadInt32();
@@ -2046,6 +2180,7 @@
/// </summary>
public sealed partial class ReconnectInfo : pb::IMessage<ReconnectInfo> {
private static readonly pb::MessageParser<ReconnectInfo> _parser = new pb::MessageParser<ReconnectInfo>(() => new ReconnectInfo());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<ReconnectInfo> Parser { get { return _parser; } }
@@ -2070,6 +2205,7 @@
public ReconnectInfo(ReconnectInfo other) : this() {
passed_ = other.passed_;
backoffMs_ = other.backoffMs_.Clone();
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -2113,7 +2249,7 @@
}
if (Passed != other.Passed) return false;
if(!backoffMs_.Equals(other.backoffMs_)) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -2121,6 +2257,9 @@
int hash = 1;
if (Passed != false) hash ^= Passed.GetHashCode();
hash ^= backoffMs_.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -2136,6 +2275,9 @@
output.WriteBool(Passed);
}
backoffMs_.WriteTo(output, _repeated_backoffMs_codec);
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -2145,6 +2287,9 @@
size += 1 + 1;
}
size += backoffMs_.CalculateSize(_repeated_backoffMs_codec);
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -2157,6 +2302,7 @@
Passed = other.Passed;
}
backoffMs_.Add(other.backoffMs_);
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -2165,7 +2311,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 8: {
Passed = input.ReadBool();
diff --git a/src/csharp/Grpc.IntegrationTesting/Metrics.cs b/src/csharp/Grpc.IntegrationTesting/Metrics.cs
index 84eb09a..b5d8b87 100644
--- a/src/csharp/Grpc.IntegrationTesting/Metrics.cs
+++ b/src/csharp/Grpc.IntegrationTesting/Metrics.cs
@@ -1,5 +1,7 @@
-// Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: src/proto/grpc/testing/metrics.proto
+// <auto-generated>
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: src/proto/grpc/testing/metrics.proto
+// </auto-generated>
#pragma warning disable 1591, 0612, 3021
#region Designer generated code
@@ -48,6 +50,7 @@
/// </summary>
public sealed partial class GaugeResponse : pb::IMessage<GaugeResponse> {
private static readonly pb::MessageParser<GaugeResponse> _parser = new pb::MessageParser<GaugeResponse>(() => new GaugeResponse());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<GaugeResponse> Parser { get { return _parser; } }
@@ -83,6 +86,7 @@
break;
}
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -169,10 +173,10 @@
}
if (Name != other.Name) return false;
if (LongValue != other.LongValue) return false;
- if (DoubleValue != other.DoubleValue) return false;
+ if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleValue, other.DoubleValue)) return false;
if (StringValue != other.StringValue) return false;
if (ValueCase != other.ValueCase) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -180,9 +184,12 @@
int hash = 1;
if (Name.Length != 0) hash ^= Name.GetHashCode();
if (valueCase_ == ValueOneofCase.LongValue) hash ^= LongValue.GetHashCode();
- if (valueCase_ == ValueOneofCase.DoubleValue) hash ^= DoubleValue.GetHashCode();
+ if (valueCase_ == ValueOneofCase.DoubleValue) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleValue);
if (valueCase_ == ValueOneofCase.StringValue) hash ^= StringValue.GetHashCode();
hash ^= (int) valueCase_;
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -209,6 +216,9 @@
output.WriteRawTag(34);
output.WriteString(StringValue);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -226,6 +236,9 @@
if (valueCase_ == ValueOneofCase.StringValue) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(StringValue);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -249,6 +262,7 @@
break;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -257,7 +271,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
Name = input.ReadString();
@@ -286,6 +300,7 @@
/// </summary>
public sealed partial class GaugeRequest : pb::IMessage<GaugeRequest> {
private static readonly pb::MessageParser<GaugeRequest> _parser = new pb::MessageParser<GaugeRequest>(() => new GaugeRequest());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<GaugeRequest> Parser { get { return _parser; } }
@@ -309,6 +324,7 @@
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public GaugeRequest(GaugeRequest other) : this() {
name_ = other.name_;
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -341,13 +357,16 @@
return true;
}
if (Name != other.Name) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Name.Length != 0) hash ^= Name.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -362,6 +381,9 @@
output.WriteRawTag(10);
output.WriteString(Name);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -370,6 +392,9 @@
if (Name.Length != 0) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -381,6 +406,7 @@
if (other.Name.Length != 0) {
Name = other.Name;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -389,7 +415,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
Name = input.ReadString();
@@ -403,6 +429,7 @@
public sealed partial class EmptyMessage : pb::IMessage<EmptyMessage> {
private static readonly pb::MessageParser<EmptyMessage> _parser = new pb::MessageParser<EmptyMessage>(() => new EmptyMessage());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<EmptyMessage> Parser { get { return _parser; } }
@@ -425,6 +452,7 @@
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public EmptyMessage(EmptyMessage other) : this() {
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -445,12 +473,15 @@
if (ReferenceEquals(other, this)) {
return true;
}
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -461,11 +492,17 @@
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -474,6 +511,7 @@
if (other == null) {
return;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -482,7 +520,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
}
}
diff --git a/src/csharp/Grpc.IntegrationTesting/Payloads.cs b/src/csharp/Grpc.IntegrationTesting/Payloads.cs
index fca8cda..25f34ff 100644
--- a/src/csharp/Grpc.IntegrationTesting/Payloads.cs
+++ b/src/csharp/Grpc.IntegrationTesting/Payloads.cs
@@ -1,5 +1,7 @@
-// Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: src/proto/grpc/testing/payloads.proto
+// <auto-generated>
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: src/proto/grpc/testing/payloads.proto
+// </auto-generated>
#pragma warning disable 1591, 0612, 3021
#region Designer generated code
@@ -46,6 +48,7 @@
#region Messages
public sealed partial class ByteBufferParams : pb::IMessage<ByteBufferParams> {
private static readonly pb::MessageParser<ByteBufferParams> _parser = new pb::MessageParser<ByteBufferParams>(() => new ByteBufferParams());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<ByteBufferParams> Parser { get { return _parser; } }
@@ -70,6 +73,7 @@
public ByteBufferParams(ByteBufferParams other) : this() {
reqSize_ = other.reqSize_;
respSize_ = other.respSize_;
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -114,7 +118,7 @@
}
if (ReqSize != other.ReqSize) return false;
if (RespSize != other.RespSize) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -122,6 +126,9 @@
int hash = 1;
if (ReqSize != 0) hash ^= ReqSize.GetHashCode();
if (RespSize != 0) hash ^= RespSize.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -140,6 +147,9 @@
output.WriteRawTag(16);
output.WriteInt32(RespSize);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -151,6 +161,9 @@
if (RespSize != 0) {
size += 1 + pb::CodedOutputStream.ComputeInt32Size(RespSize);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -165,6 +178,7 @@
if (other.RespSize != 0) {
RespSize = other.RespSize;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -173,7 +187,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 8: {
ReqSize = input.ReadInt32();
@@ -191,6 +205,7 @@
public sealed partial class SimpleProtoParams : pb::IMessage<SimpleProtoParams> {
private static readonly pb::MessageParser<SimpleProtoParams> _parser = new pb::MessageParser<SimpleProtoParams>(() => new SimpleProtoParams());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<SimpleProtoParams> Parser { get { return _parser; } }
@@ -215,6 +230,7 @@
public SimpleProtoParams(SimpleProtoParams other) : this() {
reqSize_ = other.reqSize_;
respSize_ = other.respSize_;
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -259,7 +275,7 @@
}
if (ReqSize != other.ReqSize) return false;
if (RespSize != other.RespSize) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -267,6 +283,9 @@
int hash = 1;
if (ReqSize != 0) hash ^= ReqSize.GetHashCode();
if (RespSize != 0) hash ^= RespSize.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -285,6 +304,9 @@
output.WriteRawTag(16);
output.WriteInt32(RespSize);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -296,6 +318,9 @@
if (RespSize != 0) {
size += 1 + pb::CodedOutputStream.ComputeInt32Size(RespSize);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -310,6 +335,7 @@
if (other.RespSize != 0) {
RespSize = other.RespSize;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -318,7 +344,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 8: {
ReqSize = input.ReadInt32();
@@ -340,6 +366,7 @@
/// </summary>
public sealed partial class ComplexProtoParams : pb::IMessage<ComplexProtoParams> {
private static readonly pb::MessageParser<ComplexProtoParams> _parser = new pb::MessageParser<ComplexProtoParams>(() => new ComplexProtoParams());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<ComplexProtoParams> Parser { get { return _parser; } }
@@ -362,6 +389,7 @@
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ComplexProtoParams(ComplexProtoParams other) : this() {
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -382,12 +410,15 @@
if (ReferenceEquals(other, this)) {
return true;
}
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -398,11 +429,17 @@
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -411,6 +448,7 @@
if (other == null) {
return;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -419,7 +457,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
}
}
@@ -429,6 +467,7 @@
public sealed partial class PayloadConfig : pb::IMessage<PayloadConfig> {
private static readonly pb::MessageParser<PayloadConfig> _parser = new pb::MessageParser<PayloadConfig>(() => new PayloadConfig());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<PayloadConfig> Parser { get { return _parser; } }
@@ -463,6 +502,7 @@
break;
}
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -540,7 +580,7 @@
if (!object.Equals(SimpleParams, other.SimpleParams)) return false;
if (!object.Equals(ComplexParams, other.ComplexParams)) return false;
if (PayloadCase != other.PayloadCase) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -550,6 +590,9 @@
if (payloadCase_ == PayloadOneofCase.SimpleParams) hash ^= SimpleParams.GetHashCode();
if (payloadCase_ == PayloadOneofCase.ComplexParams) hash ^= ComplexParams.GetHashCode();
hash ^= (int) payloadCase_;
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -572,6 +615,9 @@
output.WriteRawTag(26);
output.WriteMessage(ComplexParams);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -586,6 +632,9 @@
if (payloadCase_ == PayloadOneofCase.ComplexParams) {
size += 1 + pb::CodedOutputStream.ComputeMessageSize(ComplexParams);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -615,6 +664,7 @@
break;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -623,7 +673,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
global::Grpc.Testing.ByteBufferParams subBuilder = new global::Grpc.Testing.ByteBufferParams();
diff --git a/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioService.cs b/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioService.cs
new file mode 100644
index 0000000..707c443
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioService.cs
@@ -0,0 +1,41 @@
+// <auto-generated>
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: src/proto/grpc/testing/report_qps_scenario_service.proto
+// </auto-generated>
+#pragma warning disable 1591, 0612, 3021
+#region Designer generated code
+
+using pb = global::Google.Protobuf;
+using pbc = global::Google.Protobuf.Collections;
+using pbr = global::Google.Protobuf.Reflection;
+using scg = global::System.Collections.Generic;
+namespace Grpc.Testing {
+
+ /// <summary>Holder for reflection information generated from src/proto/grpc/testing/report_qps_scenario_service.proto</summary>
+ public static partial class ReportQpsScenarioServiceReflection {
+
+ #region Descriptor
+ /// <summary>File descriptor for src/proto/grpc/testing/report_qps_scenario_service.proto</summary>
+ public static pbr::FileDescriptor Descriptor {
+ get { return descriptor; }
+ }
+ private static pbr::FileDescriptor descriptor;
+
+ static ReportQpsScenarioServiceReflection() {
+ byte[] descriptorData = global::System.Convert.FromBase64String(
+ string.Concat(
+ "CjhzcmMvcHJvdG8vZ3JwYy90ZXN0aW5nL3JlcG9ydF9xcHNfc2NlbmFyaW9f",
+ "c2VydmljZS5wcm90bxIMZ3JwYy50ZXN0aW5nGiRzcmMvcHJvdG8vZ3JwYy90",
+ "ZXN0aW5nL2NvbnRyb2wucHJvdG8yXgoYUmVwb3J0UXBzU2NlbmFyaW9TZXJ2",
+ "aWNlEkIKDlJlcG9ydFNjZW5hcmlvEhwuZ3JwYy50ZXN0aW5nLlNjZW5hcmlv",
+ "UmVzdWx0GhIuZ3JwYy50ZXN0aW5nLlZvaWRiBnByb3RvMw=="));
+ descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+ new pbr::FileDescriptor[] { global::Grpc.Testing.ControlReflection.Descriptor, },
+ new pbr::GeneratedClrTypeInfo(null, null));
+ }
+ #endregion
+
+ }
+}
+
+#endregion Designer generated code
diff --git a/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs
new file mode 100644
index 0000000..c9c6f75
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs
@@ -0,0 +1,148 @@
+// <auto-generated>
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: src/proto/grpc/testing/report_qps_scenario_service.proto
+// </auto-generated>
+// Original file comments:
+// 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.
+//
+// An integration test service that covers all the method signature permutations
+// of unary/streaming requests/responses.
+#pragma warning disable 1591
+#region Designer generated code
+
+using grpc = global::Grpc.Core;
+
+namespace Grpc.Testing {
+ public static partial class ReportQpsScenarioService
+ {
+ static readonly string __ServiceName = "grpc.testing.ReportQpsScenarioService";
+
+ static readonly grpc::Marshaller<global::Grpc.Testing.ScenarioResult> __Marshaller_ScenarioResult = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ScenarioResult.Parser.ParseFrom);
+ static readonly grpc::Marshaller<global::Grpc.Testing.Void> __Marshaller_Void = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.Void.Parser.ParseFrom);
+
+ static readonly grpc::Method<global::Grpc.Testing.ScenarioResult, global::Grpc.Testing.Void> __Method_ReportScenario = new grpc::Method<global::Grpc.Testing.ScenarioResult, global::Grpc.Testing.Void>(
+ grpc::MethodType.Unary,
+ __ServiceName,
+ "ReportScenario",
+ __Marshaller_ScenarioResult,
+ __Marshaller_Void);
+
+ /// <summary>Service descriptor</summary>
+ public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
+ {
+ get { return global::Grpc.Testing.ReportQpsScenarioServiceReflection.Descriptor.Services[0]; }
+ }
+
+ /// <summary>Base class for server-side implementations of ReportQpsScenarioService</summary>
+ public abstract partial class ReportQpsScenarioServiceBase
+ {
+ /// <summary>
+ /// Report results of a QPS test benchmark scenario.
+ /// </summary>
+ /// <param name="request">The request received from the client.</param>
+ /// <param name="context">The context of the server-side call handler being invoked.</param>
+ /// <returns>The response to send back to the client (wrapped by a task).</returns>
+ public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.Void> ReportScenario(global::Grpc.Testing.ScenarioResult request, grpc::ServerCallContext context)
+ {
+ throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+ }
+
+ }
+
+ /// <summary>Client for ReportQpsScenarioService</summary>
+ public partial class ReportQpsScenarioServiceClient : grpc::ClientBase<ReportQpsScenarioServiceClient>
+ {
+ /// <summary>Creates a new client for ReportQpsScenarioService</summary>
+ /// <param name="channel">The channel to use to make remote calls.</param>
+ public ReportQpsScenarioServiceClient(grpc::Channel channel) : base(channel)
+ {
+ }
+ /// <summary>Creates a new client for ReportQpsScenarioService that uses a custom <c>CallInvoker</c>.</summary>
+ /// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
+ public ReportQpsScenarioServiceClient(grpc::CallInvoker callInvoker) : base(callInvoker)
+ {
+ }
+ /// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
+ protected ReportQpsScenarioServiceClient() : base()
+ {
+ }
+ /// <summary>Protected constructor to allow creation of configured clients.</summary>
+ /// <param name="configuration">The client configuration.</param>
+ protected ReportQpsScenarioServiceClient(ClientBaseConfiguration configuration) : base(configuration)
+ {
+ }
+
+ /// <summary>
+ /// Report results of a QPS test benchmark scenario.
+ /// </summary>
+ /// <param name="request">The request to send to the server.</param>
+ /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+ /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+ /// <param name="cancellationToken">An optional token for canceling the call.</param>
+ /// <returns>The response received from the server.</returns>
+ public virtual global::Grpc.Testing.Void ReportScenario(global::Grpc.Testing.ScenarioResult request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+ {
+ return ReportScenario(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+ }
+ /// <summary>
+ /// Report results of a QPS test benchmark scenario.
+ /// </summary>
+ /// <param name="request">The request to send to the server.</param>
+ /// <param name="options">The options for the call.</param>
+ /// <returns>The response received from the server.</returns>
+ public virtual global::Grpc.Testing.Void ReportScenario(global::Grpc.Testing.ScenarioResult request, grpc::CallOptions options)
+ {
+ return CallInvoker.BlockingUnaryCall(__Method_ReportScenario, null, options, request);
+ }
+ /// <summary>
+ /// Report results of a QPS test benchmark scenario.
+ /// </summary>
+ /// <param name="request">The request to send to the server.</param>
+ /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+ /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+ /// <param name="cancellationToken">An optional token for canceling the call.</param>
+ /// <returns>The call object.</returns>
+ public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.Void> ReportScenarioAsync(global::Grpc.Testing.ScenarioResult request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+ {
+ return ReportScenarioAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+ }
+ /// <summary>
+ /// Report results of a QPS test benchmark scenario.
+ /// </summary>
+ /// <param name="request">The request to send to the server.</param>
+ /// <param name="options">The options for the call.</param>
+ /// <returns>The call object.</returns>
+ public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.Void> ReportScenarioAsync(global::Grpc.Testing.ScenarioResult request, grpc::CallOptions options)
+ {
+ return CallInvoker.AsyncUnaryCall(__Method_ReportScenario, null, options, request);
+ }
+ /// <summary>Creates a new instance of client from given <c>ClientBaseConfiguration</c>.</summary>
+ protected override ReportQpsScenarioServiceClient NewInstance(ClientBaseConfiguration configuration)
+ {
+ return new ReportQpsScenarioServiceClient(configuration);
+ }
+ }
+
+ /// <summary>Creates service definition that can be registered with a server</summary>
+ /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
+ public static grpc::ServerServiceDefinition BindService(ReportQpsScenarioServiceBase serviceImpl)
+ {
+ return grpc::ServerServiceDefinition.CreateBuilder()
+ .AddMethod(__Method_ReportScenario, serviceImpl.ReportScenario).Build();
+ }
+
+ }
+}
+#endregion
diff --git a/src/csharp/Grpc.IntegrationTesting/Services.cs b/src/csharp/Grpc.IntegrationTesting/Services.cs
deleted file mode 100644
index 4b76170..0000000
--- a/src/csharp/Grpc.IntegrationTesting/Services.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-// Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: src/proto/grpc/testing/services.proto
-#pragma warning disable 1591, 0612, 3021
-#region Designer generated code
-
-using pb = global::Google.Protobuf;
-using pbc = global::Google.Protobuf.Collections;
-using pbr = global::Google.Protobuf.Reflection;
-using scg = global::System.Collections.Generic;
-namespace Grpc.Testing {
-
- /// <summary>Holder for reflection information generated from src/proto/grpc/testing/services.proto</summary>
- public static partial class ServicesReflection {
-
- #region Descriptor
- /// <summary>File descriptor for src/proto/grpc/testing/services.proto</summary>
- public static pbr::FileDescriptor Descriptor {
- get { return descriptor; }
- }
- private static pbr::FileDescriptor descriptor;
-
- static ServicesReflection() {
- byte[] descriptorData = global::System.Convert.FromBase64String(
- string.Concat(
- "CiVzcmMvcHJvdG8vZ3JwYy90ZXN0aW5nL3NlcnZpY2VzLnByb3RvEgxncnBj",
- "LnRlc3RpbmcaJXNyYy9wcm90by9ncnBjL3Rlc3RpbmcvbWVzc2FnZXMucHJv",
- "dG8aJHNyYy9wcm90by9ncnBjL3Rlc3RpbmcvY29udHJvbC5wcm90bzKmAwoQ",
- "QmVuY2htYXJrU2VydmljZRJGCglVbmFyeUNhbGwSGy5ncnBjLnRlc3Rpbmcu",
- "U2ltcGxlUmVxdWVzdBocLmdycGMudGVzdGluZy5TaW1wbGVSZXNwb25zZRJO",
- "Cg1TdHJlYW1pbmdDYWxsEhsuZ3JwYy50ZXN0aW5nLlNpbXBsZVJlcXVlc3Qa",
- "HC5ncnBjLnRlc3RpbmcuU2ltcGxlUmVzcG9uc2UoATABElIKE1N0cmVhbWlu",
- "Z0Zyb21DbGllbnQSGy5ncnBjLnRlc3RpbmcuU2ltcGxlUmVxdWVzdBocLmdy",
- "cGMudGVzdGluZy5TaW1wbGVSZXNwb25zZSgBElIKE1N0cmVhbWluZ0Zyb21T",
- "ZXJ2ZXISGy5ncnBjLnRlc3RpbmcuU2ltcGxlUmVxdWVzdBocLmdycGMudGVz",
- "dGluZy5TaW1wbGVSZXNwb25zZTABElIKEVN0cmVhbWluZ0JvdGhXYXlzEhsu",
- "Z3JwYy50ZXN0aW5nLlNpbXBsZVJlcXVlc3QaHC5ncnBjLnRlc3RpbmcuU2lt",
- "cGxlUmVzcG9uc2UoATABMpcCCg1Xb3JrZXJTZXJ2aWNlEkUKCVJ1blNlcnZl",
- "chIYLmdycGMudGVzdGluZy5TZXJ2ZXJBcmdzGhouZ3JwYy50ZXN0aW5nLlNl",
- "cnZlclN0YXR1cygBMAESRQoJUnVuQ2xpZW50EhguZ3JwYy50ZXN0aW5nLkNs",
- "aWVudEFyZ3MaGi5ncnBjLnRlc3RpbmcuQ2xpZW50U3RhdHVzKAEwARJCCglD",
- "b3JlQ291bnQSGS5ncnBjLnRlc3RpbmcuQ29yZVJlcXVlc3QaGi5ncnBjLnRl",
- "c3RpbmcuQ29yZVJlc3BvbnNlEjQKClF1aXRXb3JrZXISEi5ncnBjLnRlc3Rp",
- "bmcuVm9pZBoSLmdycGMudGVzdGluZy5Wb2lkMl4KGFJlcG9ydFFwc1NjZW5h",
- "cmlvU2VydmljZRJCCg5SZXBvcnRTY2VuYXJpbxIcLmdycGMudGVzdGluZy5T",
- "Y2VuYXJpb1Jlc3VsdBoSLmdycGMudGVzdGluZy5Wb2lkYgZwcm90bzM="));
- descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
- new pbr::FileDescriptor[] { global::Grpc.Testing.MessagesReflection.Descriptor, global::Grpc.Testing.ControlReflection.Descriptor, },
- new pbr::GeneratedClrTypeInfo(null, null));
- }
- #endregion
-
- }
-}
-
-#endregion Designer generated code
diff --git a/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs b/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs
deleted file mode 100644
index 46b328a..0000000
--- a/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs
+++ /dev/null
@@ -1,745 +0,0 @@
-// <auto-generated>
-// Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: src/proto/grpc/testing/services.proto
-// </auto-generated>
-// Original file comments:
-// 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.
-//
-// An integration test service that covers all the method signature permutations
-// of unary/streaming requests/responses.
-#pragma warning disable 1591
-#region Designer generated code
-
-using grpc = global::Grpc.Core;
-
-namespace Grpc.Testing {
- public static partial class BenchmarkService
- {
- static readonly string __ServiceName = "grpc.testing.BenchmarkService";
-
- static readonly grpc::Marshaller<global::Grpc.Testing.SimpleRequest> __Marshaller_SimpleRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.SimpleRequest.Parser.ParseFrom);
- static readonly grpc::Marshaller<global::Grpc.Testing.SimpleResponse> __Marshaller_SimpleResponse = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.SimpleResponse.Parser.ParseFrom);
-
- static readonly grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> __Method_UnaryCall = new grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse>(
- grpc::MethodType.Unary,
- __ServiceName,
- "UnaryCall",
- __Marshaller_SimpleRequest,
- __Marshaller_SimpleResponse);
-
- static readonly grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> __Method_StreamingCall = new grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse>(
- grpc::MethodType.DuplexStreaming,
- __ServiceName,
- "StreamingCall",
- __Marshaller_SimpleRequest,
- __Marshaller_SimpleResponse);
-
- static readonly grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> __Method_StreamingFromClient = new grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse>(
- grpc::MethodType.ClientStreaming,
- __ServiceName,
- "StreamingFromClient",
- __Marshaller_SimpleRequest,
- __Marshaller_SimpleResponse);
-
- static readonly grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> __Method_StreamingFromServer = new grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse>(
- grpc::MethodType.ServerStreaming,
- __ServiceName,
- "StreamingFromServer",
- __Marshaller_SimpleRequest,
- __Marshaller_SimpleResponse);
-
- static readonly grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> __Method_StreamingBothWays = new grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse>(
- grpc::MethodType.DuplexStreaming,
- __ServiceName,
- "StreamingBothWays",
- __Marshaller_SimpleRequest,
- __Marshaller_SimpleResponse);
-
- /// <summary>Service descriptor</summary>
- public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
- {
- get { return global::Grpc.Testing.ServicesReflection.Descriptor.Services[0]; }
- }
-
- /// <summary>Base class for server-side implementations of BenchmarkService</summary>
- public abstract partial class BenchmarkServiceBase
- {
- /// <summary>
- /// One request followed by one response.
- /// The server returns the client payload as-is.
- /// </summary>
- /// <param name="request">The request received from the client.</param>
- /// <param name="context">The context of the server-side call handler being invoked.</param>
- /// <returns>The response to send back to the client (wrapped by a task).</returns>
- public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.SimpleResponse> UnaryCall(global::Grpc.Testing.SimpleRequest request, grpc::ServerCallContext context)
- {
- throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
- }
-
- /// <summary>
- /// Repeated sequence of one request followed by one response.
- /// Should be called streaming ping-pong
- /// The server returns the client payload as-is on each response
- /// </summary>
- /// <param name="requestStream">Used for reading requests from the client.</param>
- /// <param name="responseStream">Used for sending responses back to the client.</param>
- /// <param name="context">The context of the server-side call handler being invoked.</param>
- /// <returns>A task indicating completion of the handler.</returns>
- public virtual global::System.Threading.Tasks.Task StreamingCall(grpc::IAsyncStreamReader<global::Grpc.Testing.SimpleRequest> requestStream, grpc::IServerStreamWriter<global::Grpc.Testing.SimpleResponse> responseStream, grpc::ServerCallContext context)
- {
- throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
- }
-
- /// <summary>
- /// Single-sided unbounded streaming from client to server
- /// The server returns the client payload as-is once the client does WritesDone
- /// </summary>
- /// <param name="requestStream">Used for reading requests from the client.</param>
- /// <param name="context">The context of the server-side call handler being invoked.</param>
- /// <returns>The response to send back to the client (wrapped by a task).</returns>
- public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.SimpleResponse> StreamingFromClient(grpc::IAsyncStreamReader<global::Grpc.Testing.SimpleRequest> requestStream, grpc::ServerCallContext context)
- {
- throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
- }
-
- /// <summary>
- /// Single-sided unbounded streaming from server to client
- /// The server repeatedly returns the client payload as-is
- /// </summary>
- /// <param name="request">The request received from the client.</param>
- /// <param name="responseStream">Used for sending responses back to the client.</param>
- /// <param name="context">The context of the server-side call handler being invoked.</param>
- /// <returns>A task indicating completion of the handler.</returns>
- public virtual global::System.Threading.Tasks.Task StreamingFromServer(global::Grpc.Testing.SimpleRequest request, grpc::IServerStreamWriter<global::Grpc.Testing.SimpleResponse> responseStream, grpc::ServerCallContext context)
- {
- throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
- }
-
- /// <summary>
- /// Two-sided unbounded streaming between server to client
- /// Both sides send the content of their own choice to the other
- /// </summary>
- /// <param name="requestStream">Used for reading requests from the client.</param>
- /// <param name="responseStream">Used for sending responses back to the client.</param>
- /// <param name="context">The context of the server-side call handler being invoked.</param>
- /// <returns>A task indicating completion of the handler.</returns>
- public virtual global::System.Threading.Tasks.Task StreamingBothWays(grpc::IAsyncStreamReader<global::Grpc.Testing.SimpleRequest> requestStream, grpc::IServerStreamWriter<global::Grpc.Testing.SimpleResponse> responseStream, grpc::ServerCallContext context)
- {
- throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
- }
-
- }
-
- /// <summary>Client for BenchmarkService</summary>
- public partial class BenchmarkServiceClient : grpc::ClientBase<BenchmarkServiceClient>
- {
- /// <summary>Creates a new client for BenchmarkService</summary>
- /// <param name="channel">The channel to use to make remote calls.</param>
- public BenchmarkServiceClient(grpc::Channel channel) : base(channel)
- {
- }
- /// <summary>Creates a new client for BenchmarkService that uses a custom <c>CallInvoker</c>.</summary>
- /// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
- public BenchmarkServiceClient(grpc::CallInvoker callInvoker) : base(callInvoker)
- {
- }
- /// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
- protected BenchmarkServiceClient() : base()
- {
- }
- /// <summary>Protected constructor to allow creation of configured clients.</summary>
- /// <param name="configuration">The client configuration.</param>
- protected BenchmarkServiceClient(ClientBaseConfiguration configuration) : base(configuration)
- {
- }
-
- /// <summary>
- /// One request followed by one response.
- /// The server returns the client payload as-is.
- /// </summary>
- /// <param name="request">The request to send to the server.</param>
- /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
- /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
- /// <param name="cancellationToken">An optional token for canceling the call.</param>
- /// <returns>The response received from the server.</returns>
- public virtual global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
- {
- return UnaryCall(request, new grpc::CallOptions(headers, deadline, cancellationToken));
- }
- /// <summary>
- /// One request followed by one response.
- /// The server returns the client payload as-is.
- /// </summary>
- /// <param name="request">The request to send to the server.</param>
- /// <param name="options">The options for the call.</param>
- /// <returns>The response received from the server.</returns>
- public virtual global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, grpc::CallOptions options)
- {
- return CallInvoker.BlockingUnaryCall(__Method_UnaryCall, null, options, request);
- }
- /// <summary>
- /// One request followed by one response.
- /// The server returns the client payload as-is.
- /// </summary>
- /// <param name="request">The request to send to the server.</param>
- /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
- /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
- /// <param name="cancellationToken">An optional token for canceling the call.</param>
- /// <returns>The call object.</returns>
- public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
- {
- return UnaryCallAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
- }
- /// <summary>
- /// One request followed by one response.
- /// The server returns the client payload as-is.
- /// </summary>
- /// <param name="request">The request to send to the server.</param>
- /// <param name="options">The options for the call.</param>
- /// <returns>The call object.</returns>
- public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, grpc::CallOptions options)
- {
- return CallInvoker.AsyncUnaryCall(__Method_UnaryCall, null, options, request);
- }
- /// <summary>
- /// Repeated sequence of one request followed by one response.
- /// Should be called streaming ping-pong
- /// The server returns the client payload as-is on each response
- /// </summary>
- /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
- /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
- /// <param name="cancellationToken">An optional token for canceling the call.</param>
- /// <returns>The call object.</returns>
- public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingCall(grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
- {
- return StreamingCall(new grpc::CallOptions(headers, deadline, cancellationToken));
- }
- /// <summary>
- /// Repeated sequence of one request followed by one response.
- /// Should be called streaming ping-pong
- /// The server returns the client payload as-is on each response
- /// </summary>
- /// <param name="options">The options for the call.</param>
- /// <returns>The call object.</returns>
- public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingCall(grpc::CallOptions options)
- {
- return CallInvoker.AsyncDuplexStreamingCall(__Method_StreamingCall, null, options);
- }
- /// <summary>
- /// Single-sided unbounded streaming from client to server
- /// The server returns the client payload as-is once the client does WritesDone
- /// </summary>
- /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
- /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
- /// <param name="cancellationToken">An optional token for canceling the call.</param>
- /// <returns>The call object.</returns>
- public virtual grpc::AsyncClientStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingFromClient(grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
- {
- return StreamingFromClient(new grpc::CallOptions(headers, deadline, cancellationToken));
- }
- /// <summary>
- /// Single-sided unbounded streaming from client to server
- /// The server returns the client payload as-is once the client does WritesDone
- /// </summary>
- /// <param name="options">The options for the call.</param>
- /// <returns>The call object.</returns>
- public virtual grpc::AsyncClientStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingFromClient(grpc::CallOptions options)
- {
- return CallInvoker.AsyncClientStreamingCall(__Method_StreamingFromClient, null, options);
- }
- /// <summary>
- /// Single-sided unbounded streaming from server to client
- /// The server repeatedly returns the client payload as-is
- /// </summary>
- /// <param name="request">The request to send to the server.</param>
- /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
- /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
- /// <param name="cancellationToken">An optional token for canceling the call.</param>
- /// <returns>The call object.</returns>
- public virtual grpc::AsyncServerStreamingCall<global::Grpc.Testing.SimpleResponse> StreamingFromServer(global::Grpc.Testing.SimpleRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
- {
- return StreamingFromServer(request, new grpc::CallOptions(headers, deadline, cancellationToken));
- }
- /// <summary>
- /// Single-sided unbounded streaming from server to client
- /// The server repeatedly returns the client payload as-is
- /// </summary>
- /// <param name="request">The request to send to the server.</param>
- /// <param name="options">The options for the call.</param>
- /// <returns>The call object.</returns>
- public virtual grpc::AsyncServerStreamingCall<global::Grpc.Testing.SimpleResponse> StreamingFromServer(global::Grpc.Testing.SimpleRequest request, grpc::CallOptions options)
- {
- return CallInvoker.AsyncServerStreamingCall(__Method_StreamingFromServer, null, options, request);
- }
- /// <summary>
- /// Two-sided unbounded streaming between server to client
- /// Both sides send the content of their own choice to the other
- /// </summary>
- /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
- /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
- /// <param name="cancellationToken">An optional token for canceling the call.</param>
- /// <returns>The call object.</returns>
- public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingBothWays(grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
- {
- return StreamingBothWays(new grpc::CallOptions(headers, deadline, cancellationToken));
- }
- /// <summary>
- /// Two-sided unbounded streaming between server to client
- /// Both sides send the content of their own choice to the other
- /// </summary>
- /// <param name="options">The options for the call.</param>
- /// <returns>The call object.</returns>
- public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingBothWays(grpc::CallOptions options)
- {
- return CallInvoker.AsyncDuplexStreamingCall(__Method_StreamingBothWays, null, options);
- }
- /// <summary>Creates a new instance of client from given <c>ClientBaseConfiguration</c>.</summary>
- protected override BenchmarkServiceClient NewInstance(ClientBaseConfiguration configuration)
- {
- return new BenchmarkServiceClient(configuration);
- }
- }
-
- /// <summary>Creates service definition that can be registered with a server</summary>
- /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
- public static grpc::ServerServiceDefinition BindService(BenchmarkServiceBase serviceImpl)
- {
- return grpc::ServerServiceDefinition.CreateBuilder()
- .AddMethod(__Method_UnaryCall, serviceImpl.UnaryCall)
- .AddMethod(__Method_StreamingCall, serviceImpl.StreamingCall)
- .AddMethod(__Method_StreamingFromClient, serviceImpl.StreamingFromClient)
- .AddMethod(__Method_StreamingFromServer, serviceImpl.StreamingFromServer)
- .AddMethod(__Method_StreamingBothWays, serviceImpl.StreamingBothWays).Build();
- }
-
- }
- public static partial class WorkerService
- {
- static readonly string __ServiceName = "grpc.testing.WorkerService";
-
- static readonly grpc::Marshaller<global::Grpc.Testing.ServerArgs> __Marshaller_ServerArgs = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ServerArgs.Parser.ParseFrom);
- static readonly grpc::Marshaller<global::Grpc.Testing.ServerStatus> __Marshaller_ServerStatus = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ServerStatus.Parser.ParseFrom);
- static readonly grpc::Marshaller<global::Grpc.Testing.ClientArgs> __Marshaller_ClientArgs = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ClientArgs.Parser.ParseFrom);
- static readonly grpc::Marshaller<global::Grpc.Testing.ClientStatus> __Marshaller_ClientStatus = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ClientStatus.Parser.ParseFrom);
- static readonly grpc::Marshaller<global::Grpc.Testing.CoreRequest> __Marshaller_CoreRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.CoreRequest.Parser.ParseFrom);
- static readonly grpc::Marshaller<global::Grpc.Testing.CoreResponse> __Marshaller_CoreResponse = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.CoreResponse.Parser.ParseFrom);
- static readonly grpc::Marshaller<global::Grpc.Testing.Void> __Marshaller_Void = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.Void.Parser.ParseFrom);
-
- static readonly grpc::Method<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> __Method_RunServer = new grpc::Method<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus>(
- grpc::MethodType.DuplexStreaming,
- __ServiceName,
- "RunServer",
- __Marshaller_ServerArgs,
- __Marshaller_ServerStatus);
-
- static readonly grpc::Method<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> __Method_RunClient = new grpc::Method<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus>(
- grpc::MethodType.DuplexStreaming,
- __ServiceName,
- "RunClient",
- __Marshaller_ClientArgs,
- __Marshaller_ClientStatus);
-
- static readonly grpc::Method<global::Grpc.Testing.CoreRequest, global::Grpc.Testing.CoreResponse> __Method_CoreCount = new grpc::Method<global::Grpc.Testing.CoreRequest, global::Grpc.Testing.CoreResponse>(
- grpc::MethodType.Unary,
- __ServiceName,
- "CoreCount",
- __Marshaller_CoreRequest,
- __Marshaller_CoreResponse);
-
- static readonly grpc::Method<global::Grpc.Testing.Void, global::Grpc.Testing.Void> __Method_QuitWorker = new grpc::Method<global::Grpc.Testing.Void, global::Grpc.Testing.Void>(
- grpc::MethodType.Unary,
- __ServiceName,
- "QuitWorker",
- __Marshaller_Void,
- __Marshaller_Void);
-
- /// <summary>Service descriptor</summary>
- public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
- {
- get { return global::Grpc.Testing.ServicesReflection.Descriptor.Services[1]; }
- }
-
- /// <summary>Base class for server-side implementations of WorkerService</summary>
- public abstract partial class WorkerServiceBase
- {
- /// <summary>
- /// Start server with specified workload.
- /// First request sent specifies the ServerConfig followed by ServerStatus
- /// response. After that, a "Mark" can be sent anytime to request the latest
- /// stats. Closing the stream will initiate shutdown of the test server
- /// and once the shutdown has finished, the OK status is sent to terminate
- /// this RPC.
- /// </summary>
- /// <param name="requestStream">Used for reading requests from the client.</param>
- /// <param name="responseStream">Used for sending responses back to the client.</param>
- /// <param name="context">The context of the server-side call handler being invoked.</param>
- /// <returns>A task indicating completion of the handler.</returns>
- public virtual global::System.Threading.Tasks.Task RunServer(grpc::IAsyncStreamReader<global::Grpc.Testing.ServerArgs> requestStream, grpc::IServerStreamWriter<global::Grpc.Testing.ServerStatus> responseStream, grpc::ServerCallContext context)
- {
- throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
- }
-
- /// <summary>
- /// Start client with specified workload.
- /// First request sent specifies the ClientConfig followed by ClientStatus
- /// response. After that, a "Mark" can be sent anytime to request the latest
- /// stats. Closing the stream will initiate shutdown of the test client
- /// and once the shutdown has finished, the OK status is sent to terminate
- /// this RPC.
- /// </summary>
- /// <param name="requestStream">Used for reading requests from the client.</param>
- /// <param name="responseStream">Used for sending responses back to the client.</param>
- /// <param name="context">The context of the server-side call handler being invoked.</param>
- /// <returns>A task indicating completion of the handler.</returns>
- public virtual global::System.Threading.Tasks.Task RunClient(grpc::IAsyncStreamReader<global::Grpc.Testing.ClientArgs> requestStream, grpc::IServerStreamWriter<global::Grpc.Testing.ClientStatus> responseStream, grpc::ServerCallContext context)
- {
- throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
- }
-
- /// <summary>
- /// Just return the core count - unary call
- /// </summary>
- /// <param name="request">The request received from the client.</param>
- /// <param name="context">The context of the server-side call handler being invoked.</param>
- /// <returns>The response to send back to the client (wrapped by a task).</returns>
- public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.CoreResponse> CoreCount(global::Grpc.Testing.CoreRequest request, grpc::ServerCallContext context)
- {
- throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
- }
-
- /// <summary>
- /// Quit this worker
- /// </summary>
- /// <param name="request">The request received from the client.</param>
- /// <param name="context">The context of the server-side call handler being invoked.</param>
- /// <returns>The response to send back to the client (wrapped by a task).</returns>
- public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.Void> QuitWorker(global::Grpc.Testing.Void request, grpc::ServerCallContext context)
- {
- throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
- }
-
- }
-
- /// <summary>Client for WorkerService</summary>
- public partial class WorkerServiceClient : grpc::ClientBase<WorkerServiceClient>
- {
- /// <summary>Creates a new client for WorkerService</summary>
- /// <param name="channel">The channel to use to make remote calls.</param>
- public WorkerServiceClient(grpc::Channel channel) : base(channel)
- {
- }
- /// <summary>Creates a new client for WorkerService that uses a custom <c>CallInvoker</c>.</summary>
- /// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
- public WorkerServiceClient(grpc::CallInvoker callInvoker) : base(callInvoker)
- {
- }
- /// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
- protected WorkerServiceClient() : base()
- {
- }
- /// <summary>Protected constructor to allow creation of configured clients.</summary>
- /// <param name="configuration">The client configuration.</param>
- protected WorkerServiceClient(ClientBaseConfiguration configuration) : base(configuration)
- {
- }
-
- /// <summary>
- /// Start server with specified workload.
- /// First request sent specifies the ServerConfig followed by ServerStatus
- /// response. After that, a "Mark" can be sent anytime to request the latest
- /// stats. Closing the stream will initiate shutdown of the test server
- /// and once the shutdown has finished, the OK status is sent to terminate
- /// this RPC.
- /// </summary>
- /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
- /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
- /// <param name="cancellationToken">An optional token for canceling the call.</param>
- /// <returns>The call object.</returns>
- public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> RunServer(grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
- {
- return RunServer(new grpc::CallOptions(headers, deadline, cancellationToken));
- }
- /// <summary>
- /// Start server with specified workload.
- /// First request sent specifies the ServerConfig followed by ServerStatus
- /// response. After that, a "Mark" can be sent anytime to request the latest
- /// stats. Closing the stream will initiate shutdown of the test server
- /// and once the shutdown has finished, the OK status is sent to terminate
- /// this RPC.
- /// </summary>
- /// <param name="options">The options for the call.</param>
- /// <returns>The call object.</returns>
- public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> RunServer(grpc::CallOptions options)
- {
- return CallInvoker.AsyncDuplexStreamingCall(__Method_RunServer, null, options);
- }
- /// <summary>
- /// Start client with specified workload.
- /// First request sent specifies the ClientConfig followed by ClientStatus
- /// response. After that, a "Mark" can be sent anytime to request the latest
- /// stats. Closing the stream will initiate shutdown of the test client
- /// and once the shutdown has finished, the OK status is sent to terminate
- /// this RPC.
- /// </summary>
- /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
- /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
- /// <param name="cancellationToken">An optional token for canceling the call.</param>
- /// <returns>The call object.</returns>
- public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> RunClient(grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
- {
- return RunClient(new grpc::CallOptions(headers, deadline, cancellationToken));
- }
- /// <summary>
- /// Start client with specified workload.
- /// First request sent specifies the ClientConfig followed by ClientStatus
- /// response. After that, a "Mark" can be sent anytime to request the latest
- /// stats. Closing the stream will initiate shutdown of the test client
- /// and once the shutdown has finished, the OK status is sent to terminate
- /// this RPC.
- /// </summary>
- /// <param name="options">The options for the call.</param>
- /// <returns>The call object.</returns>
- public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> RunClient(grpc::CallOptions options)
- {
- return CallInvoker.AsyncDuplexStreamingCall(__Method_RunClient, null, options);
- }
- /// <summary>
- /// Just return the core count - unary call
- /// </summary>
- /// <param name="request">The request to send to the server.</param>
- /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
- /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
- /// <param name="cancellationToken">An optional token for canceling the call.</param>
- /// <returns>The response received from the server.</returns>
- public virtual global::Grpc.Testing.CoreResponse CoreCount(global::Grpc.Testing.CoreRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
- {
- return CoreCount(request, new grpc::CallOptions(headers, deadline, cancellationToken));
- }
- /// <summary>
- /// Just return the core count - unary call
- /// </summary>
- /// <param name="request">The request to send to the server.</param>
- /// <param name="options">The options for the call.</param>
- /// <returns>The response received from the server.</returns>
- public virtual global::Grpc.Testing.CoreResponse CoreCount(global::Grpc.Testing.CoreRequest request, grpc::CallOptions options)
- {
- return CallInvoker.BlockingUnaryCall(__Method_CoreCount, null, options, request);
- }
- /// <summary>
- /// Just return the core count - unary call
- /// </summary>
- /// <param name="request">The request to send to the server.</param>
- /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
- /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
- /// <param name="cancellationToken">An optional token for canceling the call.</param>
- /// <returns>The call object.</returns>
- public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.CoreResponse> CoreCountAsync(global::Grpc.Testing.CoreRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
- {
- return CoreCountAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
- }
- /// <summary>
- /// Just return the core count - unary call
- /// </summary>
- /// <param name="request">The request to send to the server.</param>
- /// <param name="options">The options for the call.</param>
- /// <returns>The call object.</returns>
- public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.CoreResponse> CoreCountAsync(global::Grpc.Testing.CoreRequest request, grpc::CallOptions options)
- {
- return CallInvoker.AsyncUnaryCall(__Method_CoreCount, null, options, request);
- }
- /// <summary>
- /// Quit this worker
- /// </summary>
- /// <param name="request">The request to send to the server.</param>
- /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
- /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
- /// <param name="cancellationToken">An optional token for canceling the call.</param>
- /// <returns>The response received from the server.</returns>
- public virtual global::Grpc.Testing.Void QuitWorker(global::Grpc.Testing.Void request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
- {
- return QuitWorker(request, new grpc::CallOptions(headers, deadline, cancellationToken));
- }
- /// <summary>
- /// Quit this worker
- /// </summary>
- /// <param name="request">The request to send to the server.</param>
- /// <param name="options">The options for the call.</param>
- /// <returns>The response received from the server.</returns>
- public virtual global::Grpc.Testing.Void QuitWorker(global::Grpc.Testing.Void request, grpc::CallOptions options)
- {
- return CallInvoker.BlockingUnaryCall(__Method_QuitWorker, null, options, request);
- }
- /// <summary>
- /// Quit this worker
- /// </summary>
- /// <param name="request">The request to send to the server.</param>
- /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
- /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
- /// <param name="cancellationToken">An optional token for canceling the call.</param>
- /// <returns>The call object.</returns>
- public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.Void> QuitWorkerAsync(global::Grpc.Testing.Void request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
- {
- return QuitWorkerAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
- }
- /// <summary>
- /// Quit this worker
- /// </summary>
- /// <param name="request">The request to send to the server.</param>
- /// <param name="options">The options for the call.</param>
- /// <returns>The call object.</returns>
- public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.Void> QuitWorkerAsync(global::Grpc.Testing.Void request, grpc::CallOptions options)
- {
- return CallInvoker.AsyncUnaryCall(__Method_QuitWorker, null, options, request);
- }
- /// <summary>Creates a new instance of client from given <c>ClientBaseConfiguration</c>.</summary>
- protected override WorkerServiceClient NewInstance(ClientBaseConfiguration configuration)
- {
- return new WorkerServiceClient(configuration);
- }
- }
-
- /// <summary>Creates service definition that can be registered with a server</summary>
- /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
- public static grpc::ServerServiceDefinition BindService(WorkerServiceBase serviceImpl)
- {
- return grpc::ServerServiceDefinition.CreateBuilder()
- .AddMethod(__Method_RunServer, serviceImpl.RunServer)
- .AddMethod(__Method_RunClient, serviceImpl.RunClient)
- .AddMethod(__Method_CoreCount, serviceImpl.CoreCount)
- .AddMethod(__Method_QuitWorker, serviceImpl.QuitWorker).Build();
- }
-
- }
- public static partial class ReportQpsScenarioService
- {
- static readonly string __ServiceName = "grpc.testing.ReportQpsScenarioService";
-
- static readonly grpc::Marshaller<global::Grpc.Testing.ScenarioResult> __Marshaller_ScenarioResult = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ScenarioResult.Parser.ParseFrom);
- static readonly grpc::Marshaller<global::Grpc.Testing.Void> __Marshaller_Void = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.Void.Parser.ParseFrom);
-
- static readonly grpc::Method<global::Grpc.Testing.ScenarioResult, global::Grpc.Testing.Void> __Method_ReportScenario = new grpc::Method<global::Grpc.Testing.ScenarioResult, global::Grpc.Testing.Void>(
- grpc::MethodType.Unary,
- __ServiceName,
- "ReportScenario",
- __Marshaller_ScenarioResult,
- __Marshaller_Void);
-
- /// <summary>Service descriptor</summary>
- public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
- {
- get { return global::Grpc.Testing.ServicesReflection.Descriptor.Services[2]; }
- }
-
- /// <summary>Base class for server-side implementations of ReportQpsScenarioService</summary>
- public abstract partial class ReportQpsScenarioServiceBase
- {
- /// <summary>
- /// Report results of a QPS test benchmark scenario.
- /// </summary>
- /// <param name="request">The request received from the client.</param>
- /// <param name="context">The context of the server-side call handler being invoked.</param>
- /// <returns>The response to send back to the client (wrapped by a task).</returns>
- public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.Void> ReportScenario(global::Grpc.Testing.ScenarioResult request, grpc::ServerCallContext context)
- {
- throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
- }
-
- }
-
- /// <summary>Client for ReportQpsScenarioService</summary>
- public partial class ReportQpsScenarioServiceClient : grpc::ClientBase<ReportQpsScenarioServiceClient>
- {
- /// <summary>Creates a new client for ReportQpsScenarioService</summary>
- /// <param name="channel">The channel to use to make remote calls.</param>
- public ReportQpsScenarioServiceClient(grpc::Channel channel) : base(channel)
- {
- }
- /// <summary>Creates a new client for ReportQpsScenarioService that uses a custom <c>CallInvoker</c>.</summary>
- /// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
- public ReportQpsScenarioServiceClient(grpc::CallInvoker callInvoker) : base(callInvoker)
- {
- }
- /// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
- protected ReportQpsScenarioServiceClient() : base()
- {
- }
- /// <summary>Protected constructor to allow creation of configured clients.</summary>
- /// <param name="configuration">The client configuration.</param>
- protected ReportQpsScenarioServiceClient(ClientBaseConfiguration configuration) : base(configuration)
- {
- }
-
- /// <summary>
- /// Report results of a QPS test benchmark scenario.
- /// </summary>
- /// <param name="request">The request to send to the server.</param>
- /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
- /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
- /// <param name="cancellationToken">An optional token for canceling the call.</param>
- /// <returns>The response received from the server.</returns>
- public virtual global::Grpc.Testing.Void ReportScenario(global::Grpc.Testing.ScenarioResult request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
- {
- return ReportScenario(request, new grpc::CallOptions(headers, deadline, cancellationToken));
- }
- /// <summary>
- /// Report results of a QPS test benchmark scenario.
- /// </summary>
- /// <param name="request">The request to send to the server.</param>
- /// <param name="options">The options for the call.</param>
- /// <returns>The response received from the server.</returns>
- public virtual global::Grpc.Testing.Void ReportScenario(global::Grpc.Testing.ScenarioResult request, grpc::CallOptions options)
- {
- return CallInvoker.BlockingUnaryCall(__Method_ReportScenario, null, options, request);
- }
- /// <summary>
- /// Report results of a QPS test benchmark scenario.
- /// </summary>
- /// <param name="request">The request to send to the server.</param>
- /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
- /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
- /// <param name="cancellationToken">An optional token for canceling the call.</param>
- /// <returns>The call object.</returns>
- public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.Void> ReportScenarioAsync(global::Grpc.Testing.ScenarioResult request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
- {
- return ReportScenarioAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
- }
- /// <summary>
- /// Report results of a QPS test benchmark scenario.
- /// </summary>
- /// <param name="request">The request to send to the server.</param>
- /// <param name="options">The options for the call.</param>
- /// <returns>The call object.</returns>
- public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.Void> ReportScenarioAsync(global::Grpc.Testing.ScenarioResult request, grpc::CallOptions options)
- {
- return CallInvoker.AsyncUnaryCall(__Method_ReportScenario, null, options, request);
- }
- /// <summary>Creates a new instance of client from given <c>ClientBaseConfiguration</c>.</summary>
- protected override ReportQpsScenarioServiceClient NewInstance(ClientBaseConfiguration configuration)
- {
- return new ReportQpsScenarioServiceClient(configuration);
- }
- }
-
- /// <summary>Creates service definition that can be registered with a server</summary>
- /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
- public static grpc::ServerServiceDefinition BindService(ReportQpsScenarioServiceBase serviceImpl)
- {
- return grpc::ServerServiceDefinition.CreateBuilder()
- .AddMethod(__Method_ReportScenario, serviceImpl.ReportScenario).Build();
- }
-
- }
-}
-#endregion
diff --git a/src/csharp/Grpc.IntegrationTesting/Stats.cs b/src/csharp/Grpc.IntegrationTesting/Stats.cs
index e082ae7..8160646 100644
--- a/src/csharp/Grpc.IntegrationTesting/Stats.cs
+++ b/src/csharp/Grpc.IntegrationTesting/Stats.cs
@@ -1,5 +1,7 @@
-// Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: src/proto/grpc/testing/stats.proto
+// <auto-generated>
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: src/proto/grpc/testing/stats.proto
+// </auto-generated>
#pragma warning disable 1591, 0612, 3021
#region Designer generated code
@@ -55,6 +57,7 @@
#region Messages
public sealed partial class ServerStats : pb::IMessage<ServerStats> {
private static readonly pb::MessageParser<ServerStats> _parser = new pb::MessageParser<ServerStats>(() => new ServerStats());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<ServerStats> Parser { get { return _parser; } }
@@ -84,6 +87,7 @@
idleCpuTime_ = other.idleCpuTime_;
cqPollCount_ = other.cqPollCount_;
CoreStats = other.coreStats_ != null ? other.CoreStats.Clone() : null;
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -203,26 +207,29 @@
if (ReferenceEquals(other, this)) {
return true;
}
- if (TimeElapsed != other.TimeElapsed) return false;
- if (TimeUser != other.TimeUser) return false;
- if (TimeSystem != other.TimeSystem) return false;
+ if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(TimeElapsed, other.TimeElapsed)) return false;
+ if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(TimeUser, other.TimeUser)) return false;
+ if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(TimeSystem, other.TimeSystem)) return false;
if (TotalCpuTime != other.TotalCpuTime) return false;
if (IdleCpuTime != other.IdleCpuTime) return false;
if (CqPollCount != other.CqPollCount) return false;
if (!object.Equals(CoreStats, other.CoreStats)) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
- if (TimeElapsed != 0D) hash ^= TimeElapsed.GetHashCode();
- if (TimeUser != 0D) hash ^= TimeUser.GetHashCode();
- if (TimeSystem != 0D) hash ^= TimeSystem.GetHashCode();
+ if (TimeElapsed != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(TimeElapsed);
+ if (TimeUser != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(TimeUser);
+ if (TimeSystem != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(TimeSystem);
if (TotalCpuTime != 0UL) hash ^= TotalCpuTime.GetHashCode();
if (IdleCpuTime != 0UL) hash ^= IdleCpuTime.GetHashCode();
if (CqPollCount != 0UL) hash ^= CqPollCount.GetHashCode();
if (coreStats_ != null) hash ^= CoreStats.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -261,6 +268,9 @@
output.WriteRawTag(58);
output.WriteMessage(CoreStats);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -287,6 +297,9 @@
if (coreStats_ != null) {
size += 1 + pb::CodedOutputStream.ComputeMessageSize(CoreStats);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -319,6 +332,7 @@
}
CoreStats.MergeFrom(other.CoreStats);
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -327,7 +341,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 9: {
TimeElapsed = input.ReadDouble();
@@ -371,6 +385,7 @@
/// </summary>
public sealed partial class HistogramParams : pb::IMessage<HistogramParams> {
private static readonly pb::MessageParser<HistogramParams> _parser = new pb::MessageParser<HistogramParams>(() => new HistogramParams());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<HistogramParams> Parser { get { return _parser; } }
@@ -395,6 +410,7 @@
public HistogramParams(HistogramParams other) : this() {
resolution_ = other.resolution_;
maxPossible_ = other.maxPossible_;
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -443,16 +459,19 @@
if (ReferenceEquals(other, this)) {
return true;
}
- if (Resolution != other.Resolution) return false;
- if (MaxPossible != other.MaxPossible) return false;
- return true;
+ if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(Resolution, other.Resolution)) return false;
+ if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(MaxPossible, other.MaxPossible)) return false;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
- if (Resolution != 0D) hash ^= Resolution.GetHashCode();
- if (MaxPossible != 0D) hash ^= MaxPossible.GetHashCode();
+ if (Resolution != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(Resolution);
+ if (MaxPossible != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(MaxPossible);
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -471,6 +490,9 @@
output.WriteRawTag(17);
output.WriteDouble(MaxPossible);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -482,6 +504,9 @@
if (MaxPossible != 0D) {
size += 1 + 8;
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -496,6 +521,7 @@
if (other.MaxPossible != 0D) {
MaxPossible = other.MaxPossible;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -504,7 +530,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 9: {
Resolution = input.ReadDouble();
@@ -525,6 +551,7 @@
/// </summary>
public sealed partial class HistogramData : pb::IMessage<HistogramData> {
private static readonly pb::MessageParser<HistogramData> _parser = new pb::MessageParser<HistogramData>(() => new HistogramData());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<HistogramData> Parser { get { return _parser; } }
@@ -553,6 +580,7 @@
sum_ = other.sum_;
sumOfSquares_ = other.sumOfSquares_;
count_ = other.count_;
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -639,23 +667,26 @@
return true;
}
if(!bucket_.Equals(other.bucket_)) return false;
- if (MinSeen != other.MinSeen) return false;
- if (MaxSeen != other.MaxSeen) return false;
- if (Sum != other.Sum) return false;
- if (SumOfSquares != other.SumOfSquares) return false;
- if (Count != other.Count) return false;
- return true;
+ if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(MinSeen, other.MinSeen)) return false;
+ if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(MaxSeen, other.MaxSeen)) return false;
+ if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(Sum, other.Sum)) return false;
+ if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(SumOfSquares, other.SumOfSquares)) return false;
+ if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(Count, other.Count)) return false;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
hash ^= bucket_.GetHashCode();
- if (MinSeen != 0D) hash ^= MinSeen.GetHashCode();
- if (MaxSeen != 0D) hash ^= MaxSeen.GetHashCode();
- if (Sum != 0D) hash ^= Sum.GetHashCode();
- if (SumOfSquares != 0D) hash ^= SumOfSquares.GetHashCode();
- if (Count != 0D) hash ^= Count.GetHashCode();
+ if (MinSeen != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(MinSeen);
+ if (MaxSeen != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(MaxSeen);
+ if (Sum != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(Sum);
+ if (SumOfSquares != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(SumOfSquares);
+ if (Count != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(Count);
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -687,6 +718,9 @@
output.WriteRawTag(49);
output.WriteDouble(Count);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -708,6 +742,9 @@
if (Count != 0D) {
size += 1 + 8;
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -732,6 +769,7 @@
if (other.Count != 0D) {
Count = other.Count;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -740,7 +778,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10:
case 8: {
@@ -775,6 +813,7 @@
public sealed partial class RequestResultCount : pb::IMessage<RequestResultCount> {
private static readonly pb::MessageParser<RequestResultCount> _parser = new pb::MessageParser<RequestResultCount>(() => new RequestResultCount());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<RequestResultCount> Parser { get { return _parser; } }
@@ -799,6 +838,7 @@
public RequestResultCount(RequestResultCount other) : this() {
statusCode_ = other.statusCode_;
count_ = other.count_;
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -843,7 +883,7 @@
}
if (StatusCode != other.StatusCode) return false;
if (Count != other.Count) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -851,6 +891,9 @@
int hash = 1;
if (StatusCode != 0) hash ^= StatusCode.GetHashCode();
if (Count != 0L) hash ^= Count.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -869,6 +912,9 @@
output.WriteRawTag(16);
output.WriteInt64(Count);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -880,6 +926,9 @@
if (Count != 0L) {
size += 1 + pb::CodedOutputStream.ComputeInt64Size(Count);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -894,6 +943,7 @@
if (other.Count != 0L) {
Count = other.Count;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -902,7 +952,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 8: {
StatusCode = input.ReadInt32();
@@ -920,6 +970,7 @@
public sealed partial class ClientStats : pb::IMessage<ClientStats> {
private static readonly pb::MessageParser<ClientStats> _parser = new pb::MessageParser<ClientStats>(() => new ClientStats());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<ClientStats> Parser { get { return _parser; } }
@@ -949,6 +1000,7 @@
requestResults_ = other.requestResults_.Clone();
cqPollCount_ = other.cqPollCount_;
CoreStats = other.coreStats_ != null ? other.CoreStats.Clone() : null;
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1061,25 +1113,28 @@
return true;
}
if (!object.Equals(Latencies, other.Latencies)) return false;
- if (TimeElapsed != other.TimeElapsed) return false;
- if (TimeUser != other.TimeUser) return false;
- if (TimeSystem != other.TimeSystem) return false;
+ if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(TimeElapsed, other.TimeElapsed)) return false;
+ if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(TimeUser, other.TimeUser)) return false;
+ if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(TimeSystem, other.TimeSystem)) return false;
if(!requestResults_.Equals(other.requestResults_)) return false;
if (CqPollCount != other.CqPollCount) return false;
if (!object.Equals(CoreStats, other.CoreStats)) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (latencies_ != null) hash ^= Latencies.GetHashCode();
- if (TimeElapsed != 0D) hash ^= TimeElapsed.GetHashCode();
- if (TimeUser != 0D) hash ^= TimeUser.GetHashCode();
- if (TimeSystem != 0D) hash ^= TimeSystem.GetHashCode();
+ if (TimeElapsed != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(TimeElapsed);
+ if (TimeUser != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(TimeUser);
+ if (TimeSystem != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(TimeSystem);
hash ^= requestResults_.GetHashCode();
if (CqPollCount != 0UL) hash ^= CqPollCount.GetHashCode();
if (coreStats_ != null) hash ^= CoreStats.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -1115,6 +1170,9 @@
output.WriteRawTag(58);
output.WriteMessage(CoreStats);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1139,6 +1197,9 @@
if (coreStats_ != null) {
size += 1 + pb::CodedOutputStream.ComputeMessageSize(CoreStats);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -1172,6 +1233,7 @@
}
CoreStats.MergeFrom(other.CoreStats);
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1180,7 +1242,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
if (latencies_ == null) {
diff --git a/src/csharp/Grpc.IntegrationTesting/Test.cs b/src/csharp/Grpc.IntegrationTesting/Test.cs
index d2fa9f8..03f92c7 100644
--- a/src/csharp/Grpc.IntegrationTesting/Test.cs
+++ b/src/csharp/Grpc.IntegrationTesting/Test.cs
@@ -1,5 +1,7 @@
-// Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: src/proto/grpc/testing/test.proto
+// <auto-generated>
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: src/proto/grpc/testing/test.proto
+// </auto-generated>
#pragma warning disable 1591, 0612, 3021
#region Designer generated code
diff --git a/src/csharp/Grpc.IntegrationTesting/WorkerService.cs b/src/csharp/Grpc.IntegrationTesting/WorkerService.cs
new file mode 100644
index 0000000..6de3193
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting/WorkerService.cs
@@ -0,0 +1,45 @@
+// <auto-generated>
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: src/proto/grpc/testing/worker_service.proto
+// </auto-generated>
+#pragma warning disable 1591, 0612, 3021
+#region Designer generated code
+
+using pb = global::Google.Protobuf;
+using pbc = global::Google.Protobuf.Collections;
+using pbr = global::Google.Protobuf.Reflection;
+using scg = global::System.Collections.Generic;
+namespace Grpc.Testing {
+
+ /// <summary>Holder for reflection information generated from src/proto/grpc/testing/worker_service.proto</summary>
+ public static partial class WorkerServiceReflection {
+
+ #region Descriptor
+ /// <summary>File descriptor for src/proto/grpc/testing/worker_service.proto</summary>
+ public static pbr::FileDescriptor Descriptor {
+ get { return descriptor; }
+ }
+ private static pbr::FileDescriptor descriptor;
+
+ static WorkerServiceReflection() {
+ byte[] descriptorData = global::System.Convert.FromBase64String(
+ string.Concat(
+ "CitzcmMvcHJvdG8vZ3JwYy90ZXN0aW5nL3dvcmtlcl9zZXJ2aWNlLnByb3Rv",
+ "EgxncnBjLnRlc3RpbmcaJHNyYy9wcm90by9ncnBjL3Rlc3RpbmcvY29udHJv",
+ "bC5wcm90bzKXAgoNV29ya2VyU2VydmljZRJFCglSdW5TZXJ2ZXISGC5ncnBj",
+ "LnRlc3RpbmcuU2VydmVyQXJncxoaLmdycGMudGVzdGluZy5TZXJ2ZXJTdGF0",
+ "dXMoATABEkUKCVJ1bkNsaWVudBIYLmdycGMudGVzdGluZy5DbGllbnRBcmdz",
+ "GhouZ3JwYy50ZXN0aW5nLkNsaWVudFN0YXR1cygBMAESQgoJQ29yZUNvdW50",
+ "EhkuZ3JwYy50ZXN0aW5nLkNvcmVSZXF1ZXN0GhouZ3JwYy50ZXN0aW5nLkNv",
+ "cmVSZXNwb25zZRI0CgpRdWl0V29ya2VyEhIuZ3JwYy50ZXN0aW5nLlZvaWQa",
+ "Ei5ncnBjLnRlc3RpbmcuVm9pZGIGcHJvdG8z"));
+ descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+ new pbr::FileDescriptor[] { global::Grpc.Testing.ControlReflection.Descriptor, },
+ new pbr::GeneratedClrTypeInfo(null, null));
+ }
+ #endregion
+
+ }
+}
+
+#endregion Designer generated code
diff --git a/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs
new file mode 100644
index 0000000..ede3ace
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs
@@ -0,0 +1,326 @@
+// <auto-generated>
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: src/proto/grpc/testing/worker_service.proto
+// </auto-generated>
+// Original file comments:
+// 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.
+//
+// An integration test service that covers all the method signature permutations
+// of unary/streaming requests/responses.
+#pragma warning disable 1591
+#region Designer generated code
+
+using grpc = global::Grpc.Core;
+
+namespace Grpc.Testing {
+ public static partial class WorkerService
+ {
+ static readonly string __ServiceName = "grpc.testing.WorkerService";
+
+ static readonly grpc::Marshaller<global::Grpc.Testing.ServerArgs> __Marshaller_ServerArgs = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ServerArgs.Parser.ParseFrom);
+ static readonly grpc::Marshaller<global::Grpc.Testing.ServerStatus> __Marshaller_ServerStatus = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ServerStatus.Parser.ParseFrom);
+ static readonly grpc::Marshaller<global::Grpc.Testing.ClientArgs> __Marshaller_ClientArgs = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ClientArgs.Parser.ParseFrom);
+ static readonly grpc::Marshaller<global::Grpc.Testing.ClientStatus> __Marshaller_ClientStatus = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ClientStatus.Parser.ParseFrom);
+ static readonly grpc::Marshaller<global::Grpc.Testing.CoreRequest> __Marshaller_CoreRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.CoreRequest.Parser.ParseFrom);
+ static readonly grpc::Marshaller<global::Grpc.Testing.CoreResponse> __Marshaller_CoreResponse = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.CoreResponse.Parser.ParseFrom);
+ static readonly grpc::Marshaller<global::Grpc.Testing.Void> __Marshaller_Void = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.Void.Parser.ParseFrom);
+
+ static readonly grpc::Method<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> __Method_RunServer = new grpc::Method<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus>(
+ grpc::MethodType.DuplexStreaming,
+ __ServiceName,
+ "RunServer",
+ __Marshaller_ServerArgs,
+ __Marshaller_ServerStatus);
+
+ static readonly grpc::Method<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> __Method_RunClient = new grpc::Method<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus>(
+ grpc::MethodType.DuplexStreaming,
+ __ServiceName,
+ "RunClient",
+ __Marshaller_ClientArgs,
+ __Marshaller_ClientStatus);
+
+ static readonly grpc::Method<global::Grpc.Testing.CoreRequest, global::Grpc.Testing.CoreResponse> __Method_CoreCount = new grpc::Method<global::Grpc.Testing.CoreRequest, global::Grpc.Testing.CoreResponse>(
+ grpc::MethodType.Unary,
+ __ServiceName,
+ "CoreCount",
+ __Marshaller_CoreRequest,
+ __Marshaller_CoreResponse);
+
+ static readonly grpc::Method<global::Grpc.Testing.Void, global::Grpc.Testing.Void> __Method_QuitWorker = new grpc::Method<global::Grpc.Testing.Void, global::Grpc.Testing.Void>(
+ grpc::MethodType.Unary,
+ __ServiceName,
+ "QuitWorker",
+ __Marshaller_Void,
+ __Marshaller_Void);
+
+ /// <summary>Service descriptor</summary>
+ public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
+ {
+ get { return global::Grpc.Testing.WorkerServiceReflection.Descriptor.Services[0]; }
+ }
+
+ /// <summary>Base class for server-side implementations of WorkerService</summary>
+ public abstract partial class WorkerServiceBase
+ {
+ /// <summary>
+ /// Start server with specified workload.
+ /// First request sent specifies the ServerConfig followed by ServerStatus
+ /// response. After that, a "Mark" can be sent anytime to request the latest
+ /// stats. Closing the stream will initiate shutdown of the test server
+ /// and once the shutdown has finished, the OK status is sent to terminate
+ /// this RPC.
+ /// </summary>
+ /// <param name="requestStream">Used for reading requests from the client.</param>
+ /// <param name="responseStream">Used for sending responses back to the client.</param>
+ /// <param name="context">The context of the server-side call handler being invoked.</param>
+ /// <returns>A task indicating completion of the handler.</returns>
+ public virtual global::System.Threading.Tasks.Task RunServer(grpc::IAsyncStreamReader<global::Grpc.Testing.ServerArgs> requestStream, grpc::IServerStreamWriter<global::Grpc.Testing.ServerStatus> responseStream, grpc::ServerCallContext context)
+ {
+ throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+ }
+
+ /// <summary>
+ /// Start client with specified workload.
+ /// First request sent specifies the ClientConfig followed by ClientStatus
+ /// response. After that, a "Mark" can be sent anytime to request the latest
+ /// stats. Closing the stream will initiate shutdown of the test client
+ /// and once the shutdown has finished, the OK status is sent to terminate
+ /// this RPC.
+ /// </summary>
+ /// <param name="requestStream">Used for reading requests from the client.</param>
+ /// <param name="responseStream">Used for sending responses back to the client.</param>
+ /// <param name="context">The context of the server-side call handler being invoked.</param>
+ /// <returns>A task indicating completion of the handler.</returns>
+ public virtual global::System.Threading.Tasks.Task RunClient(grpc::IAsyncStreamReader<global::Grpc.Testing.ClientArgs> requestStream, grpc::IServerStreamWriter<global::Grpc.Testing.ClientStatus> responseStream, grpc::ServerCallContext context)
+ {
+ throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+ }
+
+ /// <summary>
+ /// Just return the core count - unary call
+ /// </summary>
+ /// <param name="request">The request received from the client.</param>
+ /// <param name="context">The context of the server-side call handler being invoked.</param>
+ /// <returns>The response to send back to the client (wrapped by a task).</returns>
+ public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.CoreResponse> CoreCount(global::Grpc.Testing.CoreRequest request, grpc::ServerCallContext context)
+ {
+ throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+ }
+
+ /// <summary>
+ /// Quit this worker
+ /// </summary>
+ /// <param name="request">The request received from the client.</param>
+ /// <param name="context">The context of the server-side call handler being invoked.</param>
+ /// <returns>The response to send back to the client (wrapped by a task).</returns>
+ public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.Void> QuitWorker(global::Grpc.Testing.Void request, grpc::ServerCallContext context)
+ {
+ throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+ }
+
+ }
+
+ /// <summary>Client for WorkerService</summary>
+ public partial class WorkerServiceClient : grpc::ClientBase<WorkerServiceClient>
+ {
+ /// <summary>Creates a new client for WorkerService</summary>
+ /// <param name="channel">The channel to use to make remote calls.</param>
+ public WorkerServiceClient(grpc::Channel channel) : base(channel)
+ {
+ }
+ /// <summary>Creates a new client for WorkerService that uses a custom <c>CallInvoker</c>.</summary>
+ /// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
+ public WorkerServiceClient(grpc::CallInvoker callInvoker) : base(callInvoker)
+ {
+ }
+ /// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
+ protected WorkerServiceClient() : base()
+ {
+ }
+ /// <summary>Protected constructor to allow creation of configured clients.</summary>
+ /// <param name="configuration">The client configuration.</param>
+ protected WorkerServiceClient(ClientBaseConfiguration configuration) : base(configuration)
+ {
+ }
+
+ /// <summary>
+ /// Start server with specified workload.
+ /// First request sent specifies the ServerConfig followed by ServerStatus
+ /// response. After that, a "Mark" can be sent anytime to request the latest
+ /// stats. Closing the stream will initiate shutdown of the test server
+ /// and once the shutdown has finished, the OK status is sent to terminate
+ /// this RPC.
+ /// </summary>
+ /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+ /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+ /// <param name="cancellationToken">An optional token for canceling the call.</param>
+ /// <returns>The call object.</returns>
+ public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> RunServer(grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+ {
+ return RunServer(new grpc::CallOptions(headers, deadline, cancellationToken));
+ }
+ /// <summary>
+ /// Start server with specified workload.
+ /// First request sent specifies the ServerConfig followed by ServerStatus
+ /// response. After that, a "Mark" can be sent anytime to request the latest
+ /// stats. Closing the stream will initiate shutdown of the test server
+ /// and once the shutdown has finished, the OK status is sent to terminate
+ /// this RPC.
+ /// </summary>
+ /// <param name="options">The options for the call.</param>
+ /// <returns>The call object.</returns>
+ public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> RunServer(grpc::CallOptions options)
+ {
+ return CallInvoker.AsyncDuplexStreamingCall(__Method_RunServer, null, options);
+ }
+ /// <summary>
+ /// Start client with specified workload.
+ /// First request sent specifies the ClientConfig followed by ClientStatus
+ /// response. After that, a "Mark" can be sent anytime to request the latest
+ /// stats. Closing the stream will initiate shutdown of the test client
+ /// and once the shutdown has finished, the OK status is sent to terminate
+ /// this RPC.
+ /// </summary>
+ /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+ /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+ /// <param name="cancellationToken">An optional token for canceling the call.</param>
+ /// <returns>The call object.</returns>
+ public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> RunClient(grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+ {
+ return RunClient(new grpc::CallOptions(headers, deadline, cancellationToken));
+ }
+ /// <summary>
+ /// Start client with specified workload.
+ /// First request sent specifies the ClientConfig followed by ClientStatus
+ /// response. After that, a "Mark" can be sent anytime to request the latest
+ /// stats. Closing the stream will initiate shutdown of the test client
+ /// and once the shutdown has finished, the OK status is sent to terminate
+ /// this RPC.
+ /// </summary>
+ /// <param name="options">The options for the call.</param>
+ /// <returns>The call object.</returns>
+ public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> RunClient(grpc::CallOptions options)
+ {
+ return CallInvoker.AsyncDuplexStreamingCall(__Method_RunClient, null, options);
+ }
+ /// <summary>
+ /// Just return the core count - unary call
+ /// </summary>
+ /// <param name="request">The request to send to the server.</param>
+ /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+ /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+ /// <param name="cancellationToken">An optional token for canceling the call.</param>
+ /// <returns>The response received from the server.</returns>
+ public virtual global::Grpc.Testing.CoreResponse CoreCount(global::Grpc.Testing.CoreRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+ {
+ return CoreCount(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+ }
+ /// <summary>
+ /// Just return the core count - unary call
+ /// </summary>
+ /// <param name="request">The request to send to the server.</param>
+ /// <param name="options">The options for the call.</param>
+ /// <returns>The response received from the server.</returns>
+ public virtual global::Grpc.Testing.CoreResponse CoreCount(global::Grpc.Testing.CoreRequest request, grpc::CallOptions options)
+ {
+ return CallInvoker.BlockingUnaryCall(__Method_CoreCount, null, options, request);
+ }
+ /// <summary>
+ /// Just return the core count - unary call
+ /// </summary>
+ /// <param name="request">The request to send to the server.</param>
+ /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+ /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+ /// <param name="cancellationToken">An optional token for canceling the call.</param>
+ /// <returns>The call object.</returns>
+ public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.CoreResponse> CoreCountAsync(global::Grpc.Testing.CoreRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+ {
+ return CoreCountAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+ }
+ /// <summary>
+ /// Just return the core count - unary call
+ /// </summary>
+ /// <param name="request">The request to send to the server.</param>
+ /// <param name="options">The options for the call.</param>
+ /// <returns>The call object.</returns>
+ public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.CoreResponse> CoreCountAsync(global::Grpc.Testing.CoreRequest request, grpc::CallOptions options)
+ {
+ return CallInvoker.AsyncUnaryCall(__Method_CoreCount, null, options, request);
+ }
+ /// <summary>
+ /// Quit this worker
+ /// </summary>
+ /// <param name="request">The request to send to the server.</param>
+ /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+ /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+ /// <param name="cancellationToken">An optional token for canceling the call.</param>
+ /// <returns>The response received from the server.</returns>
+ public virtual global::Grpc.Testing.Void QuitWorker(global::Grpc.Testing.Void request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+ {
+ return QuitWorker(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+ }
+ /// <summary>
+ /// Quit this worker
+ /// </summary>
+ /// <param name="request">The request to send to the server.</param>
+ /// <param name="options">The options for the call.</param>
+ /// <returns>The response received from the server.</returns>
+ public virtual global::Grpc.Testing.Void QuitWorker(global::Grpc.Testing.Void request, grpc::CallOptions options)
+ {
+ return CallInvoker.BlockingUnaryCall(__Method_QuitWorker, null, options, request);
+ }
+ /// <summary>
+ /// Quit this worker
+ /// </summary>
+ /// <param name="request">The request to send to the server.</param>
+ /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+ /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+ /// <param name="cancellationToken">An optional token for canceling the call.</param>
+ /// <returns>The call object.</returns>
+ public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.Void> QuitWorkerAsync(global::Grpc.Testing.Void request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+ {
+ return QuitWorkerAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+ }
+ /// <summary>
+ /// Quit this worker
+ /// </summary>
+ /// <param name="request">The request to send to the server.</param>
+ /// <param name="options">The options for the call.</param>
+ /// <returns>The call object.</returns>
+ public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.Void> QuitWorkerAsync(global::Grpc.Testing.Void request, grpc::CallOptions options)
+ {
+ return CallInvoker.AsyncUnaryCall(__Method_QuitWorker, null, options, request);
+ }
+ /// <summary>Creates a new instance of client from given <c>ClientBaseConfiguration</c>.</summary>
+ protected override WorkerServiceClient NewInstance(ClientBaseConfiguration configuration)
+ {
+ return new WorkerServiceClient(configuration);
+ }
+ }
+
+ /// <summary>Creates service definition that can be registered with a server</summary>
+ /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
+ public static grpc::ServerServiceDefinition BindService(WorkerServiceBase serviceImpl)
+ {
+ return grpc::ServerServiceDefinition.CreateBuilder()
+ .AddMethod(__Method_RunServer, serviceImpl.RunServer)
+ .AddMethod(__Method_RunClient, serviceImpl.RunClient)
+ .AddMethod(__Method_CoreCount, serviceImpl.CoreCount)
+ .AddMethod(__Method_QuitWorker, serviceImpl.QuitWorker).Build();
+ }
+
+ }
+}
+#endregion
diff --git a/src/csharp/Grpc.Reflection/Reflection.cs b/src/csharp/Grpc.Reflection/Reflection.cs
index 60090e5..84b2a0a 100644
--- a/src/csharp/Grpc.Reflection/Reflection.cs
+++ b/src/csharp/Grpc.Reflection/Reflection.cs
@@ -1,5 +1,7 @@
-// Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: grpc/reflection/v1alpha/reflection.proto
+// <auto-generated>
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: grpc/reflection/v1alpha/reflection.proto
+// </auto-generated>
#pragma warning disable 1591, 0612, 3021
#region Designer generated code
@@ -74,6 +76,7 @@
/// </summary>
public sealed partial class ServerReflectionRequest : pb::IMessage<ServerReflectionRequest> {
private static readonly pb::MessageParser<ServerReflectionRequest> _parser = new pb::MessageParser<ServerReflectionRequest>(() => new ServerReflectionRequest());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<ServerReflectionRequest> Parser { get { return _parser; } }
@@ -115,6 +118,7 @@
break;
}
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -256,7 +260,7 @@
if (AllExtensionNumbersOfType != other.AllExtensionNumbersOfType) return false;
if (ListServices != other.ListServices) return false;
if (MessageRequestCase != other.MessageRequestCase) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -269,6 +273,9 @@
if (messageRequestCase_ == MessageRequestOneofCase.AllExtensionNumbersOfType) hash ^= AllExtensionNumbersOfType.GetHashCode();
if (messageRequestCase_ == MessageRequestOneofCase.ListServices) hash ^= ListServices.GetHashCode();
hash ^= (int) messageRequestCase_;
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -303,6 +310,9 @@
output.WriteRawTag(58);
output.WriteString(ListServices);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -326,6 +336,9 @@
if (messageRequestCase_ == MessageRequestOneofCase.ListServices) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(ListServices);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -358,6 +371,7 @@
break;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -366,7 +380,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
Host = input.ReadString();
@@ -409,6 +423,7 @@
/// </summary>
public sealed partial class ExtensionRequest : pb::IMessage<ExtensionRequest> {
private static readonly pb::MessageParser<ExtensionRequest> _parser = new pb::MessageParser<ExtensionRequest>(() => new ExtensionRequest());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<ExtensionRequest> Parser { get { return _parser; } }
@@ -433,6 +448,7 @@
public ExtensionRequest(ExtensionRequest other) : this() {
containingType_ = other.containingType_;
extensionNumber_ = other.extensionNumber_;
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -480,7 +496,7 @@
}
if (ContainingType != other.ContainingType) return false;
if (ExtensionNumber != other.ExtensionNumber) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -488,6 +504,9 @@
int hash = 1;
if (ContainingType.Length != 0) hash ^= ContainingType.GetHashCode();
if (ExtensionNumber != 0) hash ^= ExtensionNumber.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -506,6 +525,9 @@
output.WriteRawTag(16);
output.WriteInt32(ExtensionNumber);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -517,6 +539,9 @@
if (ExtensionNumber != 0) {
size += 1 + pb::CodedOutputStream.ComputeInt32Size(ExtensionNumber);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -531,6 +556,7 @@
if (other.ExtensionNumber != 0) {
ExtensionNumber = other.ExtensionNumber;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -539,7 +565,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
ContainingType = input.ReadString();
@@ -560,6 +586,7 @@
/// </summary>
public sealed partial class ServerReflectionResponse : pb::IMessage<ServerReflectionResponse> {
private static readonly pb::MessageParser<ServerReflectionResponse> _parser = new pb::MessageParser<ServerReflectionResponse>(() => new ServerReflectionResponse());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<ServerReflectionResponse> Parser { get { return _parser; } }
@@ -599,6 +626,7 @@
break;
}
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -730,7 +758,7 @@
if (!object.Equals(ListServicesResponse, other.ListServicesResponse)) return false;
if (!object.Equals(ErrorResponse, other.ErrorResponse)) return false;
if (MessageResponseCase != other.MessageResponseCase) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -743,6 +771,9 @@
if (messageResponseCase_ == MessageResponseOneofCase.ListServicesResponse) hash ^= ListServicesResponse.GetHashCode();
if (messageResponseCase_ == MessageResponseOneofCase.ErrorResponse) hash ^= ErrorResponse.GetHashCode();
hash ^= (int) messageResponseCase_;
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -777,6 +808,9 @@
output.WriteRawTag(58);
output.WriteMessage(ErrorResponse);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -800,6 +834,9 @@
if (messageResponseCase_ == MessageResponseOneofCase.ErrorResponse) {
size += 1 + pb::CodedOutputStream.ComputeMessageSize(ErrorResponse);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -844,6 +881,7 @@
break;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -852,7 +890,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
ValidHost = input.ReadString();
@@ -914,6 +952,7 @@
/// </summary>
public sealed partial class FileDescriptorResponse : pb::IMessage<FileDescriptorResponse> {
private static readonly pb::MessageParser<FileDescriptorResponse> _parser = new pb::MessageParser<FileDescriptorResponse>(() => new FileDescriptorResponse());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<FileDescriptorResponse> Parser { get { return _parser; } }
@@ -937,6 +976,7 @@
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public FileDescriptorResponse(FileDescriptorResponse other) : this() {
fileDescriptorProto_ = other.fileDescriptorProto_.Clone();
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -973,13 +1013,16 @@
return true;
}
if(!fileDescriptorProto_.Equals(other.fileDescriptorProto_)) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
hash ^= fileDescriptorProto_.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -991,12 +1034,18 @@
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
fileDescriptorProto_.WriteTo(output, _repeated_fileDescriptorProto_codec);
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
size += fileDescriptorProto_.CalculateSize(_repeated_fileDescriptorProto_codec);
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -1006,6 +1055,7 @@
return;
}
fileDescriptorProto_.Add(other.fileDescriptorProto_);
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1014,7 +1064,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
fileDescriptorProto_.AddEntriesFrom(input, _repeated_fileDescriptorProto_codec);
@@ -1032,6 +1082,7 @@
/// </summary>
public sealed partial class ExtensionNumberResponse : pb::IMessage<ExtensionNumberResponse> {
private static readonly pb::MessageParser<ExtensionNumberResponse> _parser = new pb::MessageParser<ExtensionNumberResponse>(() => new ExtensionNumberResponse());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<ExtensionNumberResponse> Parser { get { return _parser; } }
@@ -1056,6 +1107,7 @@
public ExtensionNumberResponse(ExtensionNumberResponse other) : this() {
baseTypeName_ = other.baseTypeName_;
extensionNumber_ = other.extensionNumber_.Clone();
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1103,7 +1155,7 @@
}
if (BaseTypeName != other.BaseTypeName) return false;
if(!extensionNumber_.Equals(other.extensionNumber_)) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1111,6 +1163,9 @@
int hash = 1;
if (BaseTypeName.Length != 0) hash ^= BaseTypeName.GetHashCode();
hash ^= extensionNumber_.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -1126,6 +1181,9 @@
output.WriteString(BaseTypeName);
}
extensionNumber_.WriteTo(output, _repeated_extensionNumber_codec);
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1135,6 +1193,9 @@
size += 1 + pb::CodedOutputStream.ComputeStringSize(BaseTypeName);
}
size += extensionNumber_.CalculateSize(_repeated_extensionNumber_codec);
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -1147,6 +1208,7 @@
BaseTypeName = other.BaseTypeName;
}
extensionNumber_.Add(other.extensionNumber_);
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1155,7 +1217,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
BaseTypeName = input.ReadString();
@@ -1177,6 +1239,7 @@
/// </summary>
public sealed partial class ListServiceResponse : pb::IMessage<ListServiceResponse> {
private static readonly pb::MessageParser<ListServiceResponse> _parser = new pb::MessageParser<ListServiceResponse>(() => new ListServiceResponse());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<ListServiceResponse> Parser { get { return _parser; } }
@@ -1200,6 +1263,7 @@
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ListServiceResponse(ListServiceResponse other) : this() {
service_ = other.service_.Clone();
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1235,13 +1299,16 @@
return true;
}
if(!service_.Equals(other.service_)) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
hash ^= service_.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -1253,12 +1320,18 @@
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
service_.WriteTo(output, _repeated_service_codec);
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
size += service_.CalculateSize(_repeated_service_codec);
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -1268,6 +1341,7 @@
return;
}
service_.Add(other.service_);
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1276,7 +1350,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
service_.AddEntriesFrom(input, _repeated_service_codec);
@@ -1294,6 +1368,7 @@
/// </summary>
public sealed partial class ServiceResponse : pb::IMessage<ServiceResponse> {
private static readonly pb::MessageParser<ServiceResponse> _parser = new pb::MessageParser<ServiceResponse>(() => new ServiceResponse());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<ServiceResponse> Parser { get { return _parser; } }
@@ -1317,6 +1392,7 @@
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ServiceResponse(ServiceResponse other) : this() {
name_ = other.name_;
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1353,13 +1429,16 @@
return true;
}
if (Name != other.Name) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Name.Length != 0) hash ^= Name.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -1374,6 +1453,9 @@
output.WriteRawTag(10);
output.WriteString(Name);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1382,6 +1464,9 @@
if (Name.Length != 0) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -1393,6 +1478,7 @@
if (other.Name.Length != 0) {
Name = other.Name;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1401,7 +1487,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
Name = input.ReadString();
@@ -1418,6 +1504,7 @@
/// </summary>
public sealed partial class ErrorResponse : pb::IMessage<ErrorResponse> {
private static readonly pb::MessageParser<ErrorResponse> _parser = new pb::MessageParser<ErrorResponse>(() => new ErrorResponse());
+ private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<ErrorResponse> Parser { get { return _parser; } }
@@ -1442,6 +1529,7 @@
public ErrorResponse(ErrorResponse other) : this() {
errorCode_ = other.errorCode_;
errorMessage_ = other.errorMessage_;
+ _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1489,7 +1577,7 @@
}
if (ErrorCode != other.ErrorCode) return false;
if (ErrorMessage != other.ErrorMessage) return false;
- return true;
+ return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1497,6 +1585,9 @@
int hash = 1;
if (ErrorCode != 0) hash ^= ErrorCode.GetHashCode();
if (ErrorMessage.Length != 0) hash ^= ErrorMessage.GetHashCode();
+ if (_unknownFields != null) {
+ hash ^= _unknownFields.GetHashCode();
+ }
return hash;
}
@@ -1515,6 +1606,9 @@
output.WriteRawTag(18);
output.WriteString(ErrorMessage);
}
+ if (_unknownFields != null) {
+ _unknownFields.WriteTo(output);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1526,6 +1620,9 @@
if (ErrorMessage.Length != 0) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(ErrorMessage);
}
+ if (_unknownFields != null) {
+ size += _unknownFields.CalculateSize();
+ }
return size;
}
@@ -1540,6 +1637,7 @@
if (other.ErrorMessage.Length != 0) {
ErrorMessage = other.ErrorMessage;
}
+ _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1548,7 +1646,7 @@
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- input.SkipLastField();
+ _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 8: {
ErrorCode = input.ReadInt32();
diff --git a/src/csharp/README.md b/src/csharp/README.md
index 6821ad2..e117e66 100644
--- a/src/csharp/README.md
+++ b/src/csharp/README.md
@@ -16,16 +16,17 @@
When using gRPC C# under .NET Core you only need to [install .NET Core](https://www.microsoft.com/net/core).
-- Windows: .NET Framework 4.5+, Visual Studio 2013, 2015, 2017
-- Linux: Mono 4+, MonoDevelop 5.9+ (with NuGet add-in installed)
-- Mac OS X: Xamarin Studio 5.9+
+In addition to that, you can also use gRPC C# with these runtimes / IDEs
+- Windows: .NET Framework 4.5+, Visual Studio 2013, 2015, 2017, Visual Studio Code
+- Linux: Mono 4+, Visual Studio Code, MonoDevelop 5.9+
+- Mac OS X: Mono 4+, Visual Studio Code, Xamarin Studio 5.9+
HOW TO USE
--------------
**Windows, Linux, Mac OS X**
-- Open Visual Studio / MonoDevelop / Xamarin Studio and start a new project/solution.
+- Open Visual Studio / MonoDevelop / Xamarin Studio and start a new project/solution (alternatively, you can create a new project from command line with `dotnet` SDK)
- Add the [Grpc](https://www.nuget.org/packages/Grpc/) NuGet package as a dependency (Project options -> Manage NuGet Packages).
@@ -37,12 +38,23 @@
You only need to go through these steps if you are planning to develop gRPC C#.
If you are a user of gRPC C#, go to Usage section above.
+**Prerequisites for contributors**
+
+- [dotnet SDK](https://www.microsoft.com/net/core)
+- [Mono 4+](https://www.mono-project.com/) (only needed for Linux and MacOS)
+- Prerequisites mentioned in [INSTALL.md](../../INSTALL.md#pre-requisites)
+ to be able to compile the native code.
+
**Windows, Linux or Mac OS X**
-- The easiest way to build is using the `run_tests.py` script that will take care of building the `grpc_csharp_ext` native library:
+- The easiest way to build is using the `run_tests.py` script that will take care of building the `grpc_csharp_ext` native library.
+
```
+ # NOTE: make sure all necessary git submodules with dependencies
+ # are available by running "git submodule update --init"
+
# from the gRPC repository root
- $ python tools/run_tests/run_tests.py -c dbg -l csharp --build_only
+ $ python tools/run_tests/run_tests.py -l csharp -c dbg --build_only
```
- Use Visual Studio 2017 (on Windows) to open the solution `Grpc.sln` or use Visual Studio Code with C# extension (on Linux and Mac). gRPC C# code has been migrated to
@@ -57,11 +69,12 @@
Under Visual Studio, make sure NUnit test adapter is installed (under "Extensions and Updates").
Then you should be able to run all the tests using Test Explorer.
-gRPC team uses a Python script to simplify facilitate running tests for
+gRPC team uses a Python script to facilitate running tests for
different languages.
```
-tools/run_tests/run_tests.py -l csharp
+# from the gRPC repository root
+$ python tools/run_tests/run_tests.py -l csharp -c dbg
```
DOCUMENTATION
diff --git a/src/csharp/build_packages_dotnetcli.bat b/src/csharp/build_packages_dotnetcli.bat
index 7639173..924d7b1 100755
--- a/src/csharp/build_packages_dotnetcli.bat
+++ b/src/csharp/build_packages_dotnetcli.bat
@@ -13,7 +13,7 @@
@rem limitations under the License.
@rem Current package versions
-set VERSION=1.11.0-dev
+set VERSION=1.13.0-dev
@rem Adjust the location of nuget.exe
set NUGET=C:\nuget\nuget.exe
diff --git a/src/csharp/build_packages_dotnetcli.sh b/src/csharp/build_packages_dotnetcli.sh
index 1b73614..5c73a8f 100755
--- a/src/csharp/build_packages_dotnetcli.sh
+++ b/src/csharp/build_packages_dotnetcli.sh
@@ -45,7 +45,7 @@
dotnet pack --configuration Release Grpc.HealthCheck --output ../../../artifacts
dotnet pack --configuration Release Grpc.Reflection --output ../../../artifacts
-nuget pack Grpc.nuspec -Version "1.11.0-dev" -OutputDirectory ../../artifacts
-nuget pack Grpc.Tools.nuspec -Version "1.11.0-dev" -OutputDirectory ../../artifacts
+nuget pack Grpc.nuspec -Version "1.13.0-dev" -OutputDirectory ../../artifacts
+nuget pack Grpc.Tools.nuspec -Version "1.13.0-dev" -OutputDirectory ../../artifacts
(cd ../../artifacts && zip csharp_nugets_dotnetcli.zip *.nupkg)
diff --git a/src/csharp/experimental/build_native_ext_for_android.sh b/src/csharp/experimental/build_native_ext_for_android.sh
index 958778e..8197df7 100755
--- a/src/csharp/experimental/build_native_ext_for_android.sh
+++ b/src/csharp/experimental/build_native_ext_for_android.sh
@@ -23,7 +23,7 @@
cd build
# set to the location where Android SDK is installed
-ANDROID_NDK_PATH="$HOME/android-ndk-r16b"
+# e.g. ANDROID_NDK_PATH="$HOME/android-ndk-r16b"
cmake ../.. \
-DCMAKE_SYSTEM_NAME=Android \
diff --git a/src/csharp/generate_proto_csharp.sh b/src/csharp/generate_proto_csharp.sh
index 299dc3f..1a38f86 100755
--- a/src/csharp/generate_proto_csharp.sh
+++ b/src/csharp/generate_proto_csharp.sh
@@ -42,4 +42,4 @@
# don't match the package names. Setting -I to the correct value src/proto
# breaks the code generation.
$PROTOC --plugin=$PLUGIN --csharp_out=$TESTING_DIR --grpc_out=$TESTING_DIR \
- -I . src/proto/grpc/testing/{control,echo_messages,empty,messages,metrics,payloads,services,stats,test}.proto
+ -I . src/proto/grpc/testing/{control,echo_messages,empty,messages,metrics,payloads,benchmark_service,report_qps_scenario_service,worker_service,stats,test}.proto
diff --git a/src/csharp/global.json b/src/csharp/global.json
deleted file mode 100644
index 815be4b..0000000
--- a/src/csharp/global.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "sdk": {
- "version": "2.1.4"
- }
-}
diff --git "a/src/objective-c/\041ProtoCompiler-gRPCPlugin.podspec" "b/src/objective-c/\041ProtoCompiler-gRPCPlugin.podspec"
index 954beed..515dc91 100644
--- "a/src/objective-c/\041ProtoCompiler-gRPCPlugin.podspec"
+++ "b/src/objective-c/\041ProtoCompiler-gRPCPlugin.podspec"
@@ -42,7 +42,7 @@
# exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed
# before them.
s.name = '!ProtoCompiler-gRPCPlugin'
- v = '1.11.0-dev'
+ v = '1.13.0-dev'
s.version = v
s.summary = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.'
s.description = <<-DESC
diff --git a/src/objective-c/BoringSSL.podspec b/src/objective-c/BoringSSL.podspec
index 8a32e97..ff55320 100644
--- a/src/objective-c/BoringSSL.podspec
+++ b/src/objective-c/BoringSSL.podspec
@@ -31,7 +31,7 @@
Pod::Spec.new do |s|
s.name = 'BoringSSL'
- version = '10.0'
+ version = '10.0.2'
s.version = version
s.summary = 'BoringSSL is a fork of OpenSSL that is designed to meet Google’s needs.'
# Adapted from the homepage:
@@ -67,11 +67,9 @@
# "The name and email addresses of the library maintainers, not the Podspec maintainer."
s.authors = 'Adam Langley', 'David Benjamin', 'Matt Braithwaite'
- versions = version.split('.')
- major_version = versions[0] + '.0'
s.source = {
:git => 'https://boringssl.googlesource.com/boringssl',
- :tag => "version_for_cocoapods_#{major_version}",
+ :commit => "a20bb7ff8bb5057065a2e7941249773f9676cf45",
}
s.ios.deployment_target = '5.0'
@@ -123,7 +121,8 @@
'ssl/**/*.{h,cc}',
'*.{h,c}',
'crypto/*.{h,c}',
- 'crypto/**/*.{h,c}'
+ 'crypto/**/*.{h,c}',
+ 'third_party/fiat/*.{h,c}'
ss.private_header_files = 'ssl/*.h',
'ssl/**/*.h',
'*.h',
diff --git a/src/objective-c/GRPCClient/GRPCCall+ChannelArg.h b/src/objective-c/GRPCClient/GRPCCall+ChannelArg.h
index 18d4597..c05ba54 100644
--- a/src/objective-c/GRPCClient/GRPCCall+ChannelArg.h
+++ b/src/objective-c/GRPCClient/GRPCCall+ChannelArg.h
@@ -39,11 +39,20 @@
/** The default response size limit is 4MB. Set this to override that default. */
+ (void)setResponseSizeLimit:(NSUInteger)limit forHost:(nonnull NSString *)host;
-+ (void)closeOpenConnections DEPRECATED_MSG_ATTRIBUTE("The API for this feature is experimental, "
- "and might be removed or modified at any "
- "time.");
++ (void)closeOpenConnections DEPRECATED_MSG_ATTRIBUTE(
+ "The API for this feature is experimental, "
+ "and might be removed or modified at any "
+ "time.");
-+ (void)setDefaultCompressMethod:(GRPCCompressAlgorithm)algorithm
- forhost:(nonnull NSString *)host;
++ (void)setDefaultCompressMethod:(GRPCCompressAlgorithm)algorithm forhost:(nonnull NSString *)host;
+
+/** Enable keepalive and configure keepalive parameters. A user should call this function once to
+ * enable keepalive for a particular host. gRPC client sends a ping after every \a interval ms to
+ * check if the transport is still alive. After waiting for \a timeout ms, if the client does not
+ * receive the ping ack, it closes the transport; all pending calls to this host will fail with
+ * error GRPC_STATUS_INTERNAL with error information "keepalive watchdog timeout". */
++ (void)setKeepaliveWithInterval:(int)interval
+ timeout:(int)timeout
+ forHost:(nonnull NSString *)host;
@end
diff --git a/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m b/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m
index 805e54b..8f9c1b9 100644
--- a/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m
+++ b/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m
@@ -38,8 +38,7 @@
[GRPCHost flushChannelCache];
}
-+ (void)setDefaultCompressMethod:(GRPCCompressAlgorithm)algorithm
- forhost:(nonnull NSString *)host {
++ (void)setDefaultCompressMethod:(GRPCCompressAlgorithm)algorithm forhost:(nonnull NSString *)host {
GRPCHost *hostConfig = [GRPCHost hostWithAddress:host];
switch (algorithm) {
case GRPCCompressNone:
@@ -57,4 +56,12 @@
}
}
++ (void)setKeepaliveWithInterval:(int)interval
+ timeout:(int)timeout
+ forHost:(nonnull NSString *)host {
+ GRPCHost *hostConfig = [GRPCHost hostWithAddress:host];
+ hostConfig.keepaliveInterval = interval;
+ hostConfig.keepaliveTimeout = timeout;
+}
+
@end
diff --git a/src/objective-c/GRPCClient/GRPCCall+ChannelCredentials.h b/src/objective-c/GRPCClient/GRPCCall+ChannelCredentials.h
index c0d36b5..d7d15c4 100644
--- a/src/objective-c/GRPCClient/GRPCCall+ChannelCredentials.h
+++ b/src/objective-c/GRPCClient/GRPCCall+ChannelCredentials.h
@@ -26,7 +26,7 @@
*/
+ (BOOL)setTLSPEMRootCerts:(nullable NSString *)pemRootCert
forHost:(nonnull NSString *)host
- error:(NSError * _Nullable * _Nullable)errorPtr;
+ error:(NSError *_Nullable *_Nullable)errorPtr;
/**
* Configures @c host with TLS/SSL Client Credentials and optionally trusted root Certificate
* Authorities. If @c pemRootCerts is nil, the default CA Certificates bundled with gRPC will be
@@ -36,6 +36,6 @@
withPrivateKey:(nullable NSString *)pemPrivateKey
withCertChain:(nullable NSString *)pemCertChain
forHost:(nonnull NSString *)host
- error:(NSError * _Nullable * _Nullable)errorPtr;
+ error:(NSError *_Nullable *_Nullable)errorPtr;
@end
diff --git a/src/objective-c/GRPCClient/GRPCCall+ChannelCredentials.m b/src/objective-c/GRPCClient/GRPCCall+ChannelCredentials.m
index 00f3e4e..2689ec2 100644
--- a/src/objective-c/GRPCClient/GRPCCall+ChannelCredentials.m
+++ b/src/objective-c/GRPCClient/GRPCCall+ChannelCredentials.m
@@ -28,24 +28,23 @@
forHost:(nonnull NSString *)host
error:(NSError **)errorPtr {
if (!host) {
- [NSException raise:NSInvalidArgumentException
- format:@"host must be provided."];
+ [NSException raise:NSInvalidArgumentException format:@"host must be provided."];
}
GRPCHost *hostConfig = [GRPCHost hostWithAddress:host];
return [hostConfig setTLSPEMRootCerts:pemRootCerts
- withPrivateKey:pemPrivateKey
- withCertChain:pemCertChain
- error:errorPtr];
+ withPrivateKey:pemPrivateKey
+ withCertChain:pemCertChain
+ error:errorPtr];
}
+ (BOOL)setTLSPEMRootCerts:(nullable NSString *)pemRootCerts
forHost:(nonnull NSString *)host
error:(NSError **)errorPtr {
return [GRPCCall setTLSPEMRootCerts:pemRootCerts
- withPrivateKey:nil
- withCertChain:nil
- forHost:host
- error:errorPtr];
+ withPrivateKey:nil
+ withCertChain:nil
+ forHost:host
+ error:errorPtr];
}
@end
diff --git a/src/objective-c/GRPCClient/GRPCCall+Cronet.h b/src/objective-c/GRPCClient/GRPCCall+Cronet.h
index e084bf1..2a5f6e9 100644
--- a/src/objective-c/GRPCClient/GRPCCall+Cronet.h
+++ b/src/objective-c/GRPCClient/GRPCCall+Cronet.h
@@ -32,11 +32,11 @@
* all subsequent RPCs will use Cronet transport. The method is not thread
* safe.
*/
-+(void)useCronetWithEngine:(stream_engine *)engine;
++ (void)useCronetWithEngine:(stream_engine*)engine;
-+(stream_engine *)cronetEngine;
++ (stream_engine*)cronetEngine;
-+(BOOL)isUsingCronet;
++ (BOOL)isUsingCronet;
@end
#endif
diff --git a/src/objective-c/GRPCClient/GRPCCall+GID.h b/src/objective-c/GRPCClient/GRPCCall+GID.h
index 3ee732e..8293e92 100644
--- a/src/objective-c/GRPCClient/GRPCCall+GID.h
+++ b/src/objective-c/GRPCClient/GRPCCall+GID.h
@@ -16,14 +16,14 @@
*
*/
-#import "GRPCCall.h"
#import "GRPCCall+OAuth2.h"
+#import "GRPCCall.h"
#import <Google/SignIn.h>
/**
* Extend GIDSignIn class to comply GRPCAuthorizationProtocol
*/
-@interface GIDSignIn (GRPC) <GRPCAuthorizationProtocol>
+@interface GIDSignIn (GRPC)<GRPCAuthorizationProtocol>
- (void)getTokenWithHandler:(void (^)(NSString *token))hander;
@end
diff --git a/src/objective-c/GRPCClient/GRPCCall+OAuth2.m b/src/objective-c/GRPCClient/GRPCCall+OAuth2.m
index 8451ebe..3292b6c 100644
--- a/src/objective-c/GRPCClient/GRPCCall+OAuth2.m
+++ b/src/objective-c/GRPCClient/GRPCCall+OAuth2.m
@@ -20,9 +20,9 @@
#import "GRPCCall+OAuth2.h"
-static NSString * const kAuthorizationHeader = @"authorization";
-static NSString * const kBearerPrefix = @"Bearer ";
-static NSString * const kChallengeHeader = @"www-authenticate";
+static NSString *const kAuthorizationHeader = @"authorization";
+static NSString *const kBearerPrefix = @"Bearer ";
+static NSString *const kChallengeHeader = @"www-authenticate";
@implementation GRPCCall (OAuth2)
@dynamic tokenProvider;
diff --git a/src/objective-c/GRPCClient/GRPCCall+Tests.m b/src/objective-c/GRPCClient/GRPCCall+Tests.m
index aa9af9f..0db3ad6 100644
--- a/src/objective-c/GRPCClient/GRPCCall+Tests.m
+++ b/src/objective-c/GRPCClient/GRPCCall+Tests.m
@@ -29,11 +29,10 @@
[NSException raise:NSInvalidArgumentException format:@"host, path and name must be provided."];
}
NSError *error = nil;
- NSString *certs = [NSString stringWithContentsOfFile:certsPath
- encoding:NSUTF8StringEncoding
- error:&error];
+ NSString *certs =
+ [NSString stringWithContentsOfFile:certsPath encoding:NSUTF8StringEncoding error:&error];
if (error != nil) {
- [NSException raise:[error localizedDescription] format:@"failed to load certs"];
+ [NSException raise:[error localizedDescription] format:@"failed to load certs"];
}
GRPCHost *hostConfig = [GRPCHost hostWithAddress:host];
diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h
index df563ca..e0ef8b1 100644
--- a/src/objective-c/GRPCClient/GRPCCall.h
+++ b/src/objective-c/GRPCClient/GRPCCall.h
@@ -147,7 +147,8 @@
GRPCCallSafetyDefault = 0,
/** Signal that the call is idempotent. gRPC is free to use PUT verb. */
GRPCCallSafetyIdempotentRequest = 1,
- /** Signal that the call is cacheable and will not affect server state. gRPC is free to use GET verb. */
+ /** Signal that the call is cacheable and will not affect server state. gRPC is free to use GET
+ verb. */
GRPCCallSafetyCacheableRequest = 2,
};
@@ -167,7 +168,7 @@
* The authority for the RPC. If nil, the default authority will be used. This property must be nil
* when Cronet transport is enabled.
*/
-@property (atomic, copy, readwrite) NSString *serverName;
+@property(atomic, copy, readwrite) NSString *serverName;
/**
* The timeout for the RPC call in seconds. If set to 0, the call will not timeout. If set to
@@ -265,7 +266,7 @@
/** This protocol is kept for backwards compatibility with existing code. */
DEPRECATED_MSG_ATTRIBUTE("Use NSDictionary or NSMutableDictionary instead.")
-@protocol GRPCRequestHeaders <NSObject>
+@protocol GRPCRequestHeaders<NSObject>
@property(nonatomic, readonly) NSUInteger count;
- (id)objectForKeyedSubscript:(id)key;
@@ -278,6 +279,6 @@
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated"
/** This is only needed for backwards-compatibility. */
-@interface NSMutableDictionary (GRPCRequestHeaders) <GRPCRequestHeaders>
+@interface NSMutableDictionary (GRPCRequestHeaders)<GRPCRequestHeaders>
@end
#pragma clang diagnostic pop
diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m
index ea658bc..75dda9d 100644
--- a/src/objective-c/GRPCClient/GRPCCall.m
+++ b/src/objective-c/GRPCClient/GRPCCall.m
@@ -20,10 +20,10 @@
#import "GRPCCall+OAuth2.h"
-#include <grpc/grpc.h>
-#include <grpc/support/time.h>
#import <RxLibrary/GRXConcurrentWriteable.h>
#import <RxLibrary/GRXImmediateSingleWriter.h>
+#include <grpc/grpc.h>
+#include <grpc/support/time.h>
#import "private/GRPCConnectivityMonitor.h"
#import "private/GRPCHost.h"
@@ -38,14 +38,14 @@
// and RECV_STATUS_ON_CLIENT.
NSInteger kMaxClientBatch = 6;
-NSString * const kGRPCHeadersKey = @"io.grpc.HeadersKey";
-NSString * const kGRPCTrailersKey = @"io.grpc.TrailersKey";
+NSString *const kGRPCHeadersKey = @"io.grpc.HeadersKey";
+NSString *const kGRPCTrailersKey = @"io.grpc.TrailersKey";
static NSMutableDictionary *callFlags;
-static NSString * const kAuthorizationHeader = @"authorization";
-static NSString * const kBearerPrefix = @"Bearer ";
+static NSString *const kAuthorizationHeader = @"authorization";
+static NSString *const kBearerPrefix = @"Bearer ";
-@interface GRPCCall () <GRXWriteable>
+@interface GRPCCall ()<GRXWriteable>
// Make them read-write.
@property(atomic, strong) NSDictionary *responseHeaders;
@property(atomic, strong) NSDictionary *responseTrailers;
@@ -196,9 +196,6 @@
_state = GRXWriterStateFinished;
}
- // If the call isn't retained anywhere else, it can be deallocated now.
- _retainSelf = nil;
-
// If there were still request messages coming, stop them.
@synchronized(_requestWriter) {
_requestWriter.state = GRXWriterStateFinished;
@@ -211,6 +208,9 @@
}
[GRPCConnectivityMonitor unregisterObserver:self];
+
+ // If the call isn't retained anywhere else, it can be deallocated now.
+ _retainSelf = nil;
}
- (void)cancelCall {
@@ -219,9 +219,11 @@
}
- (void)cancel {
- [self maybeFinishWithError:[NSError errorWithDomain:kGRPCErrorDomain
- code:GRPCErrorCodeCancelled
- userInfo:@{NSLocalizedDescriptionKey: @"Canceled by app"}]];
+ [self
+ maybeFinishWithError:[NSError
+ errorWithDomain:kGRPCErrorDomain
+ code:GRPCErrorCodeCancelled
+ userInfo:@{NSLocalizedDescriptionKey : @"Canceled by app"}]];
if (!self.isWaitingForToken) {
[self cancelCall];
@@ -254,9 +256,9 @@
// Only called from the call queue.
// The handler will be called from the network queue.
-- (void)startReadWithHandler:(void(^)(grpc_byte_buffer *))handler {
+- (void)startReadWithHandler:(void (^)(grpc_byte_buffer *))handler {
// TODO(jcanizales): Add error handlers for async failures
- [_wrappedCall startBatchWithOperations:@[[[GRPCOpRecvMessage alloc] initWithHandler:handler]]];
+ [_wrappedCall startBatchWithOperations:@[ [[GRPCOpRecvMessage alloc] initWithHandler:handler] ]];
}
// Called initially from the network queue once response headers are received,
@@ -287,15 +289,21 @@
// don't want to throw, because the app shouldn't crash for a behavior
// that's on the hands of any server to have. Instead we finish and ask
// the server to cancel.
- [strongSelf maybeFinishWithError:[NSError errorWithDomain:kGRPCErrorDomain
- code:GRPCErrorCodeResourceExhausted
- userInfo:@{NSLocalizedDescriptionKey: @"Client does not have enough memory to hold the server response."}]];
+ [strongSelf
+ maybeFinishWithError:[NSError errorWithDomain:kGRPCErrorDomain
+ code:GRPCErrorCodeResourceExhausted
+ userInfo:@{
+ NSLocalizedDescriptionKey :
+ @"Client does not have enough memory to "
+ @"hold the server response."
+ }]];
[strongSelf cancelCall];
return;
}
- [strongWriteable enqueueValue:data completionHandler:^{
- [strongSelf startNextRead];
- }];
+ [strongWriteable enqueueValue:data
+ completionHandler:^{
+ [strongSelf startNextRead];
+ }];
}];
});
}
@@ -304,11 +312,12 @@
- (void)sendHeaders:(NSDictionary *)headers {
// TODO(jcanizales): Add error handlers for async failures
- GRPCOpSendMetadata *op = [[GRPCOpSendMetadata alloc] initWithMetadata:headers
- flags:[GRPCCall callFlagsForHost:_host path:_path]
- handler:nil]; // No clean-up needed after SEND_INITIAL_METADATA
+ GRPCOpSendMetadata *op = [[GRPCOpSendMetadata alloc]
+ initWithMetadata:headers
+ flags:[GRPCCall callFlagsForHost:_host path:_path]
+ handler:nil]; // No clean-up needed after SEND_INITIAL_METADATA
if (!_unaryCall) {
- [_wrappedCall startBatchWithOperations:@[op]];
+ [_wrappedCall startBatchWithOperations:@[ op ]];
} else {
[_unaryOpBatch addObject:op];
}
@@ -321,9 +330,8 @@
// If the call is a unary call, parameter \a errorHandler will be ignored and
// the error handler of GRPCOpSendClose will be executed in case of error.
- (void)writeMessage:(NSData *)message withErrorHandler:(void (^)(void))errorHandler {
-
__weak GRPCCall *weakSelf = self;
- void(^resumingHandler)(void) = ^{
+ void (^resumingHandler)(void) = ^{
// Resume the request writer.
GRPCCall *strongSelf = weakSelf;
if (strongSelf) {
@@ -333,11 +341,10 @@
}
};
- GRPCOpSendMessage *op = [[GRPCOpSendMessage alloc] initWithMessage:message
- handler:resumingHandler];
+ GRPCOpSendMessage *op =
+ [[GRPCOpSendMessage alloc] initWithMessage:message handler:resumingHandler];
if (!_unaryCall) {
- [_wrappedCall startBatchWithOperations:@[op]
- errorHandler:errorHandler];
+ [_wrappedCall startBatchWithOperations:@[ op ] errorHandler:errorHandler];
} else {
// Ignored errorHandler since it is the same as the one for GRPCOpSendClose.
// TODO (mxyan): unify the error handlers of all Ops into a single closure.
@@ -355,17 +362,8 @@
}
dispatch_async(_callQueue, ^{
- __weak GRPCCall *weakSelf = self;
- [self writeMessage:value withErrorHandler:^{
- __strong GRPCCall *strongSelf = weakSelf;
- if (strongSelf != nil) {
- [strongSelf maybeFinishWithError:[NSError errorWithDomain:kGRPCErrorDomain
- code:GRPCErrorCodeInternal
- userInfo:nil]];
- // Wrapped call must be canceled when error is reported to upper layers
- [strongSelf cancelCall];
- }
- }];
+ // Write error is not processed here. It is handled by op batch of GRPC_OP_RECV_STATUS_ON_CLIENT
+ [self writeMessage:value withErrorHandler:nil];
});
}
@@ -373,12 +371,11 @@
// network queue if the requests stream couldn't be closed successfully.
- (void)finishRequestWithErrorHandler:(void (^)(void))errorHandler {
if (!_unaryCall) {
- [_wrappedCall startBatchWithOperations:@[[[GRPCOpSendClose alloc] init]]
+ [_wrappedCall startBatchWithOperations:@[ [[GRPCOpSendClose alloc] init] ]
errorHandler:errorHandler];
} else {
[_unaryOpBatch addObject:[[GRPCOpSendClose alloc] init]];
- [_wrappedCall startBatchWithOperations:_unaryOpBatch
- errorHandler:errorHandler];
+ [_wrappedCall startBatchWithOperations:_unaryOpBatch errorHandler:errorHandler];
}
}
@@ -387,15 +384,8 @@
[self cancel];
} else {
dispatch_async(_callQueue, ^{
- __weak GRPCCall *weakSelf = self;
- [self finishRequestWithErrorHandler:^{
- __strong GRPCCall *strongSelf = weakSelf;
- [strongSelf maybeFinishWithError:[NSError errorWithDomain:kGRPCErrorDomain
- code:GRPCErrorCodeInternal
- userInfo:nil]];
- // Wrapped call must be canceled when error is reported to upper layers
- [strongSelf cancelCall];
- }];
+ // EOS error is not processed here. It is handled by op batch of GRPC_OP_RECV_STATUS_ON_CLIENT
+ [self finishRequestWithErrorHandler:nil];
});
}
}
@@ -406,13 +396,13 @@
// after this.
// The first one (headersHandler), when the response headers are received.
// The second one (completionHandler), whenever the RPC finishes for any reason.
-- (void)invokeCallWithHeadersHandler:(void(^)(NSDictionary *))headersHandler
- completionHandler:(void(^)(NSError *, NSDictionary *))completionHandler {
+- (void)invokeCallWithHeadersHandler:(void (^)(NSDictionary *))headersHandler
+ completionHandler:(void (^)(NSError *, NSDictionary *))completionHandler {
// TODO(jcanizales): Add error handlers for async failures
- [_wrappedCall startBatchWithOperations:@[[[GRPCOpRecvMetadata alloc]
- initWithHandler:headersHandler]]];
- [_wrappedCall startBatchWithOperations:@[[[GRPCOpRecvStatus alloc]
- initWithHandler:completionHandler]]];
+ [_wrappedCall
+ startBatchWithOperations:@[ [[GRPCOpRecvMetadata alloc] initWithHandler:headersHandler] ]];
+ [_wrappedCall
+ startBatchWithOperations:@[ [[GRPCOpRecvStatus alloc] initWithHandler:completionHandler] ]];
}
- (void)invokeCall {
@@ -424,30 +414,31 @@
strongSelf.responseHeaders = headers;
[strongSelf startNextRead];
}
- } completionHandler:^(NSError *error, NSDictionary *trailers) {
- __strong GRPCCall *strongSelf = weakSelf;
- if (strongSelf) {
- strongSelf.responseTrailers = trailers;
+ }
+ completionHandler:^(NSError *error, NSDictionary *trailers) {
+ __strong GRPCCall *strongSelf = weakSelf;
+ if (strongSelf) {
+ strongSelf.responseTrailers = trailers;
- if (error) {
- NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
- if (error.userInfo) {
- [userInfo addEntriesFromDictionary:error.userInfo];
+ if (error) {
+ NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
+ if (error.userInfo) {
+ [userInfo addEntriesFromDictionary:error.userInfo];
+ }
+ userInfo[kGRPCTrailersKey] = strongSelf.responseTrailers;
+ // TODO(jcanizales): The C gRPC library doesn't guarantee that the headers block will be
+ // called before this one, so an error might end up with trailers but no headers. We
+ // shouldn't call finishWithError until ater both blocks are called. It is also when
+ // this is done that we can provide a merged view of response headers and trailers in a
+ // thread-safe way.
+ if (strongSelf.responseHeaders) {
+ userInfo[kGRPCHeadersKey] = strongSelf.responseHeaders;
+ }
+ error = [NSError errorWithDomain:error.domain code:error.code userInfo:userInfo];
+ }
+ [strongSelf maybeFinishWithError:error];
}
- userInfo[kGRPCTrailersKey] = strongSelf.responseTrailers;
- // TODO(jcanizales): The C gRPC library doesn't guarantee that the headers block will be
- // called before this one, so an error might end up with trailers but no headers. We
- // shouldn't call finishWithError until ater both blocks are called. It is also when this is
- // done that we can provide a merged view of response headers and trailers in a thread-safe
- // way.
- if (strongSelf.responseHeaders) {
- userInfo[kGRPCHeadersKey] = strongSelf.responseHeaders;
- }
- error = [NSError errorWithDomain:error.domain code:error.code userInfo:userInfo];
- }
- [strongSelf maybeFinishWithError:error];
- }
- }];
+ }];
// Now that the RPC has been initiated, request writes can start.
@synchronized(_requestWriter) {
[_requestWriter startWithWriteable:self];
@@ -457,8 +448,8 @@
#pragma mark GRXWriter implementation
- (void)startCallWithWriteable:(id<GRXWriteable>)writeable {
- _responseWriteable = [[GRXConcurrentWriteable alloc] initWithWriteable:writeable
- dispatchQueue:_responseQueue];
+ _responseWriteable =
+ [[GRXConcurrentWriteable alloc] initWithWriteable:writeable dispatchQueue:_responseQueue];
_wrappedCall = [[GRPCWrappedCall alloc] initWithHost:_host
serverName:_serverName
@@ -469,8 +460,7 @@
[self sendHeaders:_requestHeaders];
[self invokeCall];
- [GRPCConnectivityMonitor registerObserver:self
- selector:@selector(connectivityChanged:)];
+ [GRPCConnectivityMonitor registerObserver:self selector:@selector(connectivityChanged:)];
}
- (void)startWithWriteable:(id<GRXWriteable>)writeable {
@@ -488,7 +478,7 @@
if (self.tokenProvider != nil) {
self.isWaitingForToken = YES;
__weak typeof(self) weakSelf = self;
- [self.tokenProvider getTokenWithHandler:^(NSString *token){
+ [self.tokenProvider getTokenWithHandler:^(NSString *token) {
typeof(self) strongSelf = weakSelf;
if (strongSelf && strongSelf.isWaitingForToken) {
if (token) {
@@ -537,7 +527,9 @@
- (void)connectivityChanged:(NSNotification *)note {
[self maybeFinishWithError:[NSError errorWithDomain:kGRPCErrorDomain
code:GRPCErrorCodeUnavailable
- userInfo:@{ NSLocalizedDescriptionKey : @"Connectivity lost." }]];
+ userInfo:@{
+ NSLocalizedDescriptionKey : @"Connectivity lost."
+ }]];
// Cancel underlying call upon this notification
[self cancelCall];
}
diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.h b/src/objective-c/GRPCClient/private/GRPCChannel.h
index d37182f..6499d43 100644
--- a/src/objective-c/GRPCClient/private/GRPCChannel.h
+++ b/src/objective-c/GRPCClient/private/GRPCChannel.h
@@ -23,7 +23,6 @@
@class GRPCCompletionQueue;
struct grpc_channel_credentials;
-
/**
* Each separate instance of this class represents at least one TCP connection to the provided host.
*/
@@ -52,8 +51,9 @@
* @c channelArgs. Only in tests should @c GRPC_SSL_TARGET_NAME_OVERRIDE_ARG channel arg be set.
*/
+ (nonnull GRPCChannel *)secureChannelWithHost:(nonnull NSString *)host
- credentials:(nonnull struct grpc_channel_credentials *)credentials
- channelArgs:(nullable NSDictionary *)channelArgs;
+ credentials:
+ (nonnull struct grpc_channel_credentials *)credentials
+ channelArgs:(nullable NSDictionary *)channelArgs;
/**
* Creates an insecure channel to the specified @c host using the specified @c channelArgs.
diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m
index b53d841..a49a489 100644
--- a/src/objective-c/GRPCClient/private/GRPCChannel.m
+++ b/src/objective-c/GRPCClient/private/GRPCChannel.m
@@ -32,7 +32,7 @@
#endif
#import "GRPCCompletionQueue.h"
-static void* copy_pointer_arg(void *p) {
+static void *copy_pointer_arg(void *p) {
// Add ref count to the object when making copy
id obj = (__bridge id)p;
return (__bridge_retained void *)obj;
@@ -43,12 +43,10 @@
CFRelease((CFTreeRef)p);
}
-static int cmp_pointer_arg(void *p, void *q) {
- return p == q;
-}
+static int cmp_pointer_arg(void *p, void *q) { return p == q; }
-static const grpc_arg_pointer_vtable objc_arg_vtable = {
- copy_pointer_arg, destroy_pointer_arg, cmp_pointer_arg};
+static const grpc_arg_pointer_vtable objc_arg_vtable = {copy_pointer_arg, destroy_pointer_arg,
+ cmp_pointer_arg};
static void FreeChannelArgs(grpc_channel_args *channel_args) {
for (size_t i = 0; i < channel_args->num_args; ++i) {
@@ -124,10 +122,8 @@
if (self = [super init]) {
_channelArgs = BuildChannelArgs(channelArgs);
_host = [host copy];
- _unmanagedChannel = grpc_cronet_secure_channel_create(cronetEngine,
- _host.UTF8String,
- _channelArgs,
- NULL);
+ _unmanagedChannel =
+ grpc_cronet_secure_channel_create(cronetEngine, _host.UTF8String, _channelArgs, NULL);
}
return self;
@@ -150,8 +146,8 @@
_channelArgs = BuildChannelArgs(channelArgs);
_host = [host copy];
if (secure) {
- _unmanagedChannel = grpc_secure_channel_create(credentials, _host.UTF8String, _channelArgs,
- NULL);
+ _unmanagedChannel =
+ grpc_secure_channel_create(credentials, _host.UTF8String, _channelArgs, NULL);
} else {
_unmanagedChannel = grpc_insecure_channel_create(_host.UTF8String, _channelArgs, NULL);
}
@@ -172,8 +168,7 @@
channelArgs:(NSDictionary *)channelArgs {
stream_engine *engine = [GRPCCall cronetEngine];
if (!engine) {
- [NSException raise:NSInvalidArgumentException
- format:@"cronet_engine is NULL. Set it first."];
+ [NSException raise:NSInvalidArgumentException format:@"cronet_engine is NULL. Set it first."];
return nil;
}
return [[GRPCChannel alloc] initWithHost:host cronetEngine:engine channelArgs:channelArgs];
@@ -191,15 +186,10 @@
secure:YES
credentials:credentials
channelArgs:channelArgs];
-
}
-+ (GRPCChannel *)insecureChannelWithHost:(NSString *)host
- channelArgs:(NSDictionary *)channelArgs {
- return [[GRPCChannel alloc] initWithHost:host
- secure:NO
- credentials:NULL
- channelArgs:channelArgs];
++ (GRPCChannel *)insecureChannelWithHost:(NSString *)host channelArgs:(NSDictionary *)channelArgs {
+ return [[GRPCChannel alloc] initWithHost:host secure:NO credentials:NULL channelArgs:channelArgs];
}
- (grpc_call *)unmanagedCallWithPath:(NSString *)path
@@ -215,17 +205,13 @@
host_slice = grpc_slice_from_copied_string(serverName.UTF8String);
}
grpc_slice path_slice = grpc_slice_from_copied_string(path.UTF8String);
- gpr_timespec deadline_ms = timeout == 0 ?
- gpr_inf_future(GPR_CLOCK_REALTIME) :
- gpr_time_add(
- gpr_now(GPR_CLOCK_MONOTONIC),
- gpr_time_from_millis((int64_t)(timeout * 1000), GPR_TIMESPAN));
- grpc_call *call = grpc_channel_create_call(_unmanagedChannel,
- NULL, GRPC_PROPAGATE_DEFAULTS,
- queue.unmanagedQueue,
- path_slice,
- serverName ? &host_slice : NULL,
- deadline_ms, NULL);
+ gpr_timespec deadline_ms =
+ timeout == 0 ? gpr_inf_future(GPR_CLOCK_REALTIME)
+ : gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
+ gpr_time_from_millis((int64_t)(timeout * 1000), GPR_TIMESPAN));
+ grpc_call *call = grpc_channel_create_call(_unmanagedChannel, NULL, GRPC_PROPAGATE_DEFAULTS,
+ queue.unmanagedQueue, path_slice,
+ serverName ? &host_slice : NULL, deadline_ms, NULL);
if (serverName) {
grpc_slice_unref(host_slice);
}
diff --git a/src/objective-c/GRPCClient/private/GRPCCompletionQueue.h b/src/objective-c/GRPCClient/private/GRPCCompletionQueue.h
index 41f5da3..5b017b4 100644
--- a/src/objective-c/GRPCClient/private/GRPCCompletionQueue.h
+++ b/src/objective-c/GRPCClient/private/GRPCCompletionQueue.h
@@ -19,7 +19,7 @@
#import <Foundation/Foundation.h>
#include <grpc/grpc.h>
-typedef void(^GRPCQueueCompletionHandler)(bool success);
+typedef void (^GRPCQueueCompletionHandler)(bool success);
/**
* This class lets one more easily use |grpc_completion_queue|. To use it, pass the value of the
diff --git a/src/objective-c/GRPCClient/private/GRPCCompletionQueue.m b/src/objective-c/GRPCClient/private/GRPCCompletionQueue.m
index 7ba1978..57dbde8 100644
--- a/src/objective-c/GRPCClient/private/GRPCCompletionQueue.m
+++ b/src/objective-c/GRPCClient/private/GRPCCompletionQueue.m
@@ -53,9 +53,8 @@
dispatch_async(gDefaultConcurrentQueue, ^{
while (YES) {
// The following call blocks until an event is available.
- grpc_event event = grpc_completion_queue_next(unmanagedQueue,
- gpr_inf_future(GPR_CLOCK_REALTIME),
- NULL);
+ grpc_event event =
+ grpc_completion_queue_next(unmanagedQueue, gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
GRPCQueueCompletionHandler handler;
switch (event.type) {
case GRPC_OP_COMPLETE:
diff --git a/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.h b/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.h
index 394d217..d4b49b1 100644
--- a/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.h
+++ b/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.h
@@ -26,7 +26,7 @@
GRPCConnectivityWiFi = 3,
};
-extern NSString * _Nonnull kGRPCConnectivityNotification;
+extern NSString* _Nonnull kGRPCConnectivityNotification;
// This interface monitors OS reachability interface for any network status
// change. Parties interested in these events should register themselves as
@@ -39,8 +39,7 @@
// must have a notification method with one parameter of type
// (NSNotification *) and should pass it to parameter \a selector. The
// parameter of this notification method is not used for now.
-+ (void)registerObserver:(_Nonnull id)observer
- selector:(_Nonnull SEL)selector;
++ (void)registerObserver:(_Nonnull id)observer selector:(_Nonnull SEL)selector;
// Ungegister an object from observers of network status change.
+ (void)unregisterObserver:(_Nonnull id)observer;
diff --git a/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.m b/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.m
index 7f31c7e..a36788b 100644
--- a/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.m
+++ b/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.m
@@ -41,8 +41,8 @@
return result;
}
-static void ReachabilityCallback(
- SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void* info) {
+static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags,
+ void *info) {
GRPCConnectivityStatus newStatus = CalculateConnectivityStatus(flags);
if (newStatus != currentStatus) {
@@ -69,15 +69,14 @@
SCNetworkReachabilityContext context = {0, (__bridge void *)(self), NULL, NULL, NULL};
if (!SCNetworkReachabilitySetCallback(reachability, ReachabilityCallback, &context) ||
- !SCNetworkReachabilityScheduleWithRunLoop(
- reachability, CFRunLoopGetMain(), kCFRunLoopCommonModes)) {
+ !SCNetworkReachabilityScheduleWithRunLoop(reachability, CFRunLoopGetMain(),
+ kCFRunLoopCommonModes)) {
NSLog(@"gRPC connectivity monitor fail to set");
}
}
}
-+ (void)registerObserver:(_Nonnull id)observer
- selector:(SEL)selector {
++ (void)registerObserver:(_Nonnull id)observer selector:(SEL)selector {
[[NSNotificationCenter defaultCenter] addObserver:observer
selector:selector
name:kGRPCConnectivityNotification
diff --git a/src/objective-c/GRPCClient/private/GRPCHost.h b/src/objective-c/GRPCClient/private/GRPCHost.h
index 0215db8..6697f61 100644
--- a/src/objective-c/GRPCClient/private/GRPCHost.h
+++ b/src/objective-c/GRPCClient/private/GRPCHost.h
@@ -35,6 +35,8 @@
@property(nonatomic, copy, nullable) NSString *userAgentPrefix;
@property(nonatomic, nullable) struct grpc_channel_credentials *channelCreds;
@property(nonatomic) grpc_compression_algorithm compressAlgorithm;
+@property(nonatomic) int keepaliveInterval;
+@property(nonatomic) int keepaliveTimeout;
/** The following properties should only be modified for testing: */
@@ -45,7 +47,6 @@
/** The default response size limit is 4MB. Set this to override that default. */
@property(nonatomic, strong, nullable) NSNumber *responseSizeLimitOverride;
-
- (nullable instancetype)init NS_UNAVAILABLE;
/** Host objects initialized with the same address are the same. */
+ (nullable instancetype)hostWithAddress:(NSString *)address;
diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m
index 8568e33..bfb1fd3 100644
--- a/src/objective-c/GRPCClient/private/GRPCHost.m
+++ b/src/objective-c/GRPCClient/private/GRPCHost.m
@@ -18,10 +18,10 @@
#import "GRPCHost.h"
+#import <GRPCClient/GRPCCall+MobileLog.h>
+#import <GRPCClient/GRPCCall.h>
#include <grpc/grpc.h>
#include <grpc/grpc_security.h>
-#import <GRPCClient/GRPCCall.h>
-#import <GRPCClient/GRPCCall+MobileLog.h>
#ifdef GRPC_COMPILE_WITH_CRONET
#import <GRPCClient/GRPCCall+ChannelArg.h>
#import <GRPCClient/GRPCCall+Cronet.h>
@@ -91,16 +91,15 @@
+ (void)flushChannelCache {
@synchronized(kHostCache) {
- [kHostCache enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key,
- GRPCHost * _Nonnull host,
- BOOL * _Nonnull stop) {
+ [kHostCache enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, GRPCHost *_Nonnull host,
+ BOOL *_Nonnull stop) {
[host disconnect];
}];
}
}
+ (void)resetAllHostSettings {
- @synchronized (kHostCache) {
+ @synchronized(kHostCache) {
kHostCache = [NSMutableDictionary dictionary];
}
}
@@ -109,7 +108,10 @@
serverName:(NSString *)serverName
timeout:(NSTimeInterval)timeout
completionQueue:(GRPCCompletionQueue *)queue {
- GRPCChannel *channel;
+ // The __block attribute is to allow channel take refcount inside @synchronized block. Without
+ // this attribute, retain of channel object happens after objc_sync_exit in release builds, which
+ // may result in channel released before used. See grpc/#15033.
+ __block GRPCChannel *channel;
// This is racing -[GRPCHost disconnect].
@synchronized(self) {
if (!_channel) {
@@ -131,38 +133,38 @@
static NSError *kDefaultRootsError;
static dispatch_once_t loading;
dispatch_once(&loading, ^{
- NSString *defaultPath = @"gRPCCertificates.bundle/roots"; // .pem
+ NSString *defaultPath = @"gRPCCertificates.bundle/roots"; // .pem
// Do not use NSBundle.mainBundle, as it's nil for tests of library projects.
NSBundle *bundle = [NSBundle bundleForClass:self.class];
NSString *path = [bundle pathForResource:defaultPath ofType:@"pem"];
NSError *error;
// Files in PEM format can have non-ASCII characters in their comments (e.g. for the name of the
// issuer). Load them as UTF8 and produce an ASCII equivalent.
- NSString *contentInUTF8 = [NSString stringWithContentsOfFile:path
- encoding:NSUTF8StringEncoding
- error:&error];
+ NSString *contentInUTF8 =
+ [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error];
if (contentInUTF8 == nil) {
kDefaultRootsError = error;
return;
}
- kDefaultRootsASCII = [contentInUTF8 dataUsingEncoding:NSASCIIStringEncoding
- allowLossyConversion:YES];
+ kDefaultRootsASCII =
+ [contentInUTF8 dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
});
NSData *rootsASCII;
if (pemRootCerts != nil) {
- rootsASCII = [pemRootCerts dataUsingEncoding:NSASCIIStringEncoding
- allowLossyConversion:YES];
+ rootsASCII = [pemRootCerts dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
} else {
if (kDefaultRootsASCII == nil) {
if (errorPtr) {
*errorPtr = kDefaultRootsError;
}
- NSAssert(kDefaultRootsASCII, @"Could not read gRPCCertificates.bundle/roots.pem. This file, "
- "with the root certificates, is needed to establish secure (TLS) connections. "
- "Because the file is distributed with the gRPC library, this error is usually a sign "
- "that the library wasn't configured correctly for your project. Error: %@",
- kDefaultRootsError);
+ NSAssert(
+ kDefaultRootsASCII,
+ @"Could not read gRPCCertificates.bundle/roots.pem. This file, "
+ "with the root certificates, is needed to establish secure (TLS) connections. "
+ "Because the file is distributed with the gRPC library, this error is usually a sign "
+ "that the library wasn't configured correctly for your project. Error: %@",
+ kDefaultRootsError);
return NO;
}
rootsASCII = kDefaultRootsASCII;
@@ -173,10 +175,10 @@
creds = grpc_ssl_credentials_create(rootsASCII.bytes, NULL, NULL);
} else {
grpc_ssl_pem_key_cert_pair key_cert_pair;
- NSData *privateKeyASCII = [pemPrivateKey dataUsingEncoding:NSASCIIStringEncoding
- allowLossyConversion:YES];
- NSData *certChainASCII = [pemCertChain dataUsingEncoding:NSASCIIStringEncoding
- allowLossyConversion:YES];
+ NSData *privateKeyASCII =
+ [pemPrivateKey dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
+ NSData *certChainASCII =
+ [pemCertChain dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
key_cert_pair.private_key = privateKeyASCII.bytes;
key_cert_pair.cert_chain = certChainASCII.bytes;
creds = grpc_ssl_credentials_create(rootsASCII.bytes, &key_cert_pair, NULL);
@@ -192,7 +194,7 @@
return YES;
}
-- (NSDictionary *)channelArgs {
+- (NSDictionary *)channelArgsUsingCronet:(BOOL)useCronet {
NSMutableDictionary *args = [NSMutableDictionary dictionary];
// TODO(jcanizales): Add OS and device information (see
@@ -212,8 +214,12 @@
}
if (_compressAlgorithm != GRPC_COMPRESS_NONE) {
- args[@GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM] =
- [NSNumber numberWithInt:_compressAlgorithm];
+ args[@GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM] = [NSNumber numberWithInt:_compressAlgorithm];
+ }
+
+ if (_keepaliveInterval != 0) {
+ args[@GRPC_ARG_KEEPALIVE_TIME_MS] = [NSNumber numberWithInt:_keepaliveInterval];
+ args[@GRPC_ARG_KEEPALIVE_TIMEOUT_MS] = [NSNumber numberWithInt:_keepaliveTimeout];
}
id logConfig = [GRPCCall logConfig];
@@ -221,14 +227,19 @@
args[@GRPC_ARG_MOBILE_LOG_CONFIG] = logConfig;
}
+ if (useCronet) {
+ args[@GRPC_ARG_DISABLE_CLIENT_AUTHORITY_FILTER] = [NSNumber numberWithInt:1];
+ }
+
return args;
}
- (GRPCChannel *)newChannel {
- NSDictionary *args = [self channelArgs];
+ BOOL useCronet = NO;
#ifdef GRPC_COMPILE_WITH_CRONET
- BOOL useCronet = [GRPCCall isUsingCronet];
+ useCronet = [GRPCCall isUsingCronet];
#endif
+ NSDictionary *args = [self channelArgsUsingCronet:useCronet];
if (_secure) {
GRPCChannel *channel;
@synchronized(self) {
@@ -237,14 +248,12 @@
}
#ifdef GRPC_COMPILE_WITH_CRONET
if (useCronet) {
- channel = [GRPCChannel secureCronetChannelWithHost:_address
- channelArgs:args];
+ channel = [GRPCChannel secureCronetChannelWithHost:_address channelArgs:args];
} else
#endif
{
- channel = [GRPCChannel secureChannelWithHost:_address
- credentials:_channelCreds
- channelArgs:args];
+ channel =
+ [GRPCChannel secureChannelWithHost:_address credentials:_channelCreds channelArgs:args];
}
}
return channel;
diff --git a/src/objective-c/GRPCClient/private/GRPCOpBatchLog.h b/src/objective-c/GRPCClient/private/GRPCOpBatchLog.h
index ca4b6c5..700d19a 100644
--- a/src/objective-c/GRPCClient/private/GRPCOpBatchLog.h
+++ b/src/objective-c/GRPCClient/private/GRPCOpBatchLog.h
@@ -16,7 +16,6 @@
*
*/
-
#ifdef GRPC_TEST_OBJC
/**
diff --git a/src/objective-c/GRPCClient/private/GRPCOpBatchLog.m b/src/objective-c/GRPCClient/private/GRPCOpBatchLog.m
index fdf0fcd..0082324 100644
--- a/src/objective-c/GRPCClient/private/GRPCOpBatchLog.m
+++ b/src/objective-c/GRPCClient/private/GRPCOpBatchLog.m
@@ -25,7 +25,7 @@
@implementation GRPCOpBatchLog
+ (void)enableOpBatchLog:(BOOL)enabled {
- @synchronized (opBatchLog) {
+ @synchronized(opBatchLog) {
if (enabled) {
if (!opBatchLog) {
opBatchLog = [NSMutableArray array];
@@ -39,13 +39,13 @@
}
+ (void)addOpBatchToLog:(NSArray *)batch {
- @synchronized (opBatchLog) {
+ @synchronized(opBatchLog) {
[opBatchLog addObject:batch];
}
}
+ (NSArray *)obtainAndCleanOpBatchLog {
- @synchronized (opBatchLog) {
+ @synchronized(opBatchLog) {
NSArray *out = opBatchLog;
opBatchLog = [NSMutableArray array];
return out;
diff --git a/src/objective-c/GRPCClient/private/GRPCReachabilityFlagNames.xmacro.h b/src/objective-c/GRPCClient/private/GRPCReachabilityFlagNames.xmacro.h
index 9e32fb5..2e8e34e 100644
--- a/src/objective-c/GRPCClient/private/GRPCReachabilityFlagNames.xmacro.h
+++ b/src/objective-c/GRPCClient/private/GRPCReachabilityFlagNames.xmacro.h
@@ -17,7 +17,8 @@
*/
/**
- * "X-macro" file that lists the flags names of Apple's Network Reachability API, along with a nice
+ * "X-macro" file that lists the flags names of Apple's Network Reachability
+API, along with a nice
* Objective-C method name used to query each of them.
*
* Example usage: To generate a dictionary from flag value to name, one can do:
@@ -29,7 +30,8 @@
#undef GRPC_XMACRO_ITEM
};
- XCTAssertEqualObjects(flagNames[@(kSCNetworkReachabilityFlagsIsWWAN)], @"isCell");
+ XCTAssertEqualObjects(flagNames[@(kSCNetworkReachabilityFlagsIsWWAN)],
+@"isCell");
*/
diff --git a/src/objective-c/GRPCClient/private/GRPCRequestHeaders.m b/src/objective-c/GRPCClient/private/GRPCRequestHeaders.m
index 5de1d8f..fa4f022 100644
--- a/src/objective-c/GRPCClient/private/GRPCRequestHeaders.m
+++ b/src/objective-c/GRPCClient/private/GRPCRequestHeaders.m
@@ -23,7 +23,7 @@
#import "NSDictionary+GRPC.h"
// Used by the setter.
-static void CheckIsNonNilASCII(NSString *name, NSString* value) {
+static void CheckIsNonNilASCII(NSString *name, NSString *value) {
if (!value) {
[NSException raise:NSInvalidArgumentException format:@"%@ cannot be nil", name];
}
@@ -38,14 +38,18 @@
if ([key hasSuffix:@"-bin"]) {
if (![value isKindOfClass:NSData.class]) {
[NSException raise:NSInvalidArgumentException
- format:@"Expected NSData value for header %@ ending in \"-bin\", "
- @"instead got %@", key, value];
+ format:
+ @"Expected NSData value for header %@ ending in \"-bin\", "
+ @"instead got %@",
+ key, value];
}
} else {
if (![value isKindOfClass:NSString.class]) {
[NSException raise:NSInvalidArgumentException
- format:@"Expected NSString value for header %@ not ending in \"-bin\", "
- @"instead got %@", key, value];
+ format:
+ @"Expected NSString value for header %@ not ending in \"-bin\", "
+ @"instead got %@",
+ key, value];
}
CheckIsNonNilASCII(@"Text header value", (NSString *)value);
}
@@ -85,8 +89,8 @@
return self;
}
-- (instancetype)initWithObjects:(const id _Nonnull __unsafe_unretained *)objects
- forKeys:(const id<NSCopying> _Nonnull __unsafe_unretained *)keys
+- (instancetype)initWithObjects:(const id _Nonnull __unsafe_unretained *)objects
+ forKeys:(const id<NSCopying> _Nonnull __unsafe_unretained *)keys
count:(NSUInteger)cnt {
return [self init];
}
@@ -118,7 +122,7 @@
return _delegate.count;
}
-- (NSEnumerator * _Nonnull)keyEnumerator {
+- (NSEnumerator *_Nonnull)keyEnumerator {
return [_delegate keyEnumerator];
}
diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.h b/src/objective-c/GRPCClient/private/GRPCWrappedCall.h
index f569895..f711850 100644
--- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.h
+++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.h
@@ -29,43 +29,42 @@
@interface GRPCOpSendMetadata : GRPCOperation
-- (instancetype)initWithMetadata:(NSDictionary *)metadata
- handler:(void(^)(void))handler;
+- (instancetype)initWithMetadata:(NSDictionary *)metadata handler:(void (^)(void))handler;
- (instancetype)initWithMetadata:(NSDictionary *)metadata
flags:(uint32_t)flags
- handler:(void(^)(void))handler NS_DESIGNATED_INITIALIZER;
+ handler:(void (^)(void))handler NS_DESIGNATED_INITIALIZER;
@end
@interface GRPCOpSendMessage : GRPCOperation
- (instancetype)initWithMessage:(NSData *)message
- handler:(void(^)(void))handler NS_DESIGNATED_INITIALIZER;
+ handler:(void (^)(void))handler NS_DESIGNATED_INITIALIZER;
@end
@interface GRPCOpSendClose : GRPCOperation
-- (instancetype)initWithHandler:(void(^)(void))handler NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithHandler:(void (^)(void))handler NS_DESIGNATED_INITIALIZER;
@end
@interface GRPCOpRecvMetadata : GRPCOperation
-- (instancetype)initWithHandler:(void(^)(NSDictionary *))handler NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithHandler:(void (^)(NSDictionary *))handler NS_DESIGNATED_INITIALIZER;
@end
@interface GRPCOpRecvMessage : GRPCOperation
-- (instancetype)initWithHandler:(void(^)(grpc_byte_buffer *))handler NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithHandler:(void (^)(grpc_byte_buffer *))handler NS_DESIGNATED_INITIALIZER;
@end
@interface GRPCOpRecvStatus : GRPCOperation
-- (instancetype)initWithHandler:(void(^)(NSError *, NSDictionary *))handler
+- (instancetype)initWithHandler:(void (^)(NSError *, NSDictionary *))handler
NS_DESIGNATED_INITIALIZER;
@end
@@ -79,7 +78,7 @@
path:(NSString *)path
timeout:(NSTimeInterval)timeout NS_DESIGNATED_INITIALIZER;
-- (void)startBatchWithOperations:(NSArray *)ops errorHandler:(void(^)(void))errorHandler;
+- (void)startBatchWithOperations:(NSArray *)ops errorHandler:(void (^)(void))errorHandler;
- (void)startBatchWithOperations:(NSArray *)ops;
diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m
index 9a0fa59..f28e494 100644
--- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m
+++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m
@@ -19,29 +19,29 @@
#import "GRPCWrappedCall.h"
#import <Foundation/Foundation.h>
-#include <grpc/grpc.h>
#include <grpc/byte_buffer.h>
+#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#import "GRPCCompletionQueue.h"
#import "GRPCHost.h"
-#import "NSDictionary+GRPC.h"
#import "NSData+GRPC.h"
+#import "NSDictionary+GRPC.h"
#import "NSError+GRPC.h"
#import "GRPCOpBatchLog.h"
@implementation GRPCOperation {
-@protected
+ @protected
// Most operation subclasses don't set any flags in the grpc_op, and rely on the flag member being
// initialized to zero.
grpc_op _op;
- void(^_handler)(void);
+ void (^_handler)(void);
}
- (void)finish {
if (_handler) {
- void(^handler)(void) = _handler;
+ void (^handler)(void) = _handler;
_handler = nil;
handler();
}
@@ -54,8 +54,7 @@
return [self initWithMetadata:nil flags:0 handler:nil];
}
-- (instancetype)initWithMetadata:(NSDictionary *)metadata
- handler:(void (^)(void))handler {
+- (instancetype)initWithMetadata:(NSDictionary *)metadata handler:(void (^)(void))handler {
return [self initWithMetadata:metadata flags:0 handler:handler];
}
@@ -128,11 +127,11 @@
grpc_metadata_array _headers;
}
-- (instancetype) init {
+- (instancetype)init {
return [self initWithHandler:nil];
}
-- (instancetype) initWithHandler:(void (^)(NSDictionary *))handler {
+- (instancetype)initWithHandler:(void (^)(NSDictionary *))handler {
if (self = [super init]) {
_op.op = GRPC_OP_RECV_INITIAL_METADATA;
grpc_metadata_array_init(&_headers);
@@ -142,8 +141,8 @@
__weak typeof(self) weakSelf = self;
_handler = ^{
__strong typeof(self) strongSelf = weakSelf;
- NSDictionary *metadata = [NSDictionary
- grpc_dictionaryFromMetadataArray:strongSelf->_headers];
+ NSDictionary *metadata =
+ [NSDictionary grpc_dictionaryFromMetadataArray:strongSelf->_headers];
handler(metadata);
};
}
@@ -157,7 +156,7 @@
@end
-@implementation GRPCOpRecvMessage{
+@implementation GRPCOpRecvMessage {
grpc_byte_buffer *_receivedMessage;
}
@@ -183,18 +182,18 @@
@end
-@implementation GRPCOpRecvStatus{
+@implementation GRPCOpRecvStatus {
grpc_status_code _statusCode;
grpc_slice _details;
size_t _detailsCapacity;
grpc_metadata_array _trailers;
}
-- (instancetype) init {
+- (instancetype)init {
return [self initWithHandler:nil];
}
-- (instancetype) initWithHandler:(void (^)(NSError *, NSDictionary *))handler {
+- (instancetype)initWithHandler:(void (^)(NSError *, NSDictionary *))handler {
if (self = [super init]) {
_op.op = GRPC_OP_RECV_STATUS_ON_CLIENT;
_op.data.recv_status_on_client.status = &_statusCode;
@@ -208,10 +207,10 @@
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf) {
char *details = grpc_slice_to_c_string(strongSelf->_details);
- NSError *error = [NSError grpc_errorFromStatusCode:strongSelf->_statusCode
- details:details];
- NSDictionary *trailers = [NSDictionary
- grpc_dictionaryFromMetadataArray:strongSelf->_trailers];
+ NSError *error =
+ [NSError grpc_errorFromStatusCode:strongSelf->_statusCode details:details];
+ NSDictionary *trailers =
+ [NSDictionary grpc_dictionaryFromMetadataArray:strongSelf->_trailers];
handler(error, trailers);
gpr_free(details);
}
@@ -244,8 +243,7 @@
path:(NSString *)path
timeout:(NSTimeInterval)timeout {
if (!path || !host) {
- [NSException raise:NSInvalidArgumentException
- format:@"path and host cannot be nil."];
+ [NSException raise:NSInvalidArgumentException format:@"path and host cannot be nil."];
}
if (self = [super init]) {
@@ -270,8 +268,8 @@
}
- (void)startBatchWithOperations:(NSArray *)operations errorHandler:(void (^)(void))errorHandler {
- // Keep logs of op batches when we are running tests. Disabled when in production for improved
- // performance.
+// Keep logs of op batches when we are running tests. Disabled when in production for improved
+// performance.
#ifdef GRPC_TEST_OBJC
[GRPCOpBatchLog addOpBatchToLog:operations];
#endif
@@ -282,25 +280,26 @@
for (GRPCOperation *operation in operations) {
ops_array[i++] = operation.op;
}
- grpc_call_error error = grpc_call_start_batch(_call, ops_array, nops,
- (__bridge_retained void *)(^(bool success){
- if (!success) {
- if (errorHandler) {
- errorHandler();
- } else {
- return;
- }
- }
- for (GRPCOperation *operation in operations) {
- [operation finish];
- }
- }), NULL);
+ grpc_call_error error =
+ grpc_call_start_batch(_call, ops_array, nops, (__bridge_retained void *)(^(bool success) {
+ if (!success) {
+ if (errorHandler) {
+ errorHandler();
+ } else {
+ return;
+ }
+ }
+ for (GRPCOperation *operation in operations) {
+ [operation finish];
+ }
+ }),
+ NULL);
gpr_free(ops_array);
if (error != GRPC_CALL_OK) {
- [NSException raise:NSInternalInconsistencyException
- format:@"A precondition for calling grpc_call_start_batch wasn't met. Error %i",
- error];
+ [NSException
+ raise:NSInternalInconsistencyException
+ format:@"A precondition for calling grpc_call_start_batch wasn't met. Error %i", error];
}
}
diff --git a/src/objective-c/GRPCClient/private/NSData+GRPC.m b/src/objective-c/GRPCClient/private/NSData+GRPC.m
index 7c46594..5064da3 100644
--- a/src/objective-c/GRPCClient/private/NSData+GRPC.m
+++ b/src/objective-c/GRPCClient/private/NSData+GRPC.m
@@ -24,8 +24,8 @@
// TODO(jcanizales): Move these two incantations to the C library.
-static void MallocAndCopyByteBufferToCharArray(grpc_byte_buffer *buffer,
- size_t *length, char **array) {
+static void MallocAndCopyByteBufferToCharArray(grpc_byte_buffer *buffer, size_t *length,
+ char **array) {
grpc_byte_buffer_reader reader;
if (!grpc_byte_buffer_reader_init(&reader, buffer)) {
// grpc_byte_buffer_reader_init can fail if the data sent by the server
@@ -51,8 +51,7 @@
grpc_byte_buffer_reader_destroy(&reader);
}
-static grpc_byte_buffer *CopyCharArrayToNewByteBuffer(const char *array,
- size_t length) {
+static grpc_byte_buffer *CopyCharArrayToNewByteBuffer(const char *array, size_t length) {
grpc_slice slice = grpc_slice_from_copied_buffer(array, length);
grpc_byte_buffer *buffer = grpc_raw_byte_buffer_create(&slice, 1);
grpc_slice_unref(slice);
@@ -89,7 +88,6 @@
// to create an array of grpc_slice objects to pass to
// grpc_raw_byte_buffer_create.
// That would make it do exactly one copy, always.
- return CopyCharArrayToNewByteBuffer((const char *)self.bytes,
- (size_t)self.length);
+ return CopyCharArrayToNewByteBuffer((const char *)self.bytes, (size_t)self.length);
}
@end
diff --git a/src/objective-c/GRPCClient/private/NSDictionary+GRPC.m b/src/objective-c/GRPCClient/private/NSDictionary+GRPC.m
index 4af7cb9..af1ce0b 100644
--- a/src/objective-c/GRPCClient/private/NSDictionary+GRPC.m
+++ b/src/objective-c/GRPCClient/private/NSDictionary+GRPC.m
@@ -74,8 +74,7 @@
NSMutableDictionary *metadata = [NSMutableDictionary dictionaryWithCapacity:count];
for (grpc_metadata *entry = entries; entry < entries + count; entry++) {
char *key = grpc_slice_to_c_string(entry->key);
- NSString *name = [NSString stringWithCString:key
- encoding:NSASCIIStringEncoding];
+ NSString *name = [NSString stringWithCString:key encoding:NSASCIIStringEncoding];
gpr_free(key);
if (!name || metadata[name]) {
// Log if name is nil?
@@ -97,7 +96,7 @@
- (grpc_metadata *)grpc_metadataArray {
grpc_metadata *metadata = gpr_malloc([self count] * sizeof(grpc_metadata));
grpc_metadata *current = metadata;
- for (NSString* key in self) {
+ for (NSString *key in self) {
id value = self[key];
current->key = grpc_slice_from_copied_string(key.UTF8String);
if ([value respondsToSelector:@selector(grpc_initMetadata:)]) {
diff --git a/src/objective-c/GRPCClient/private/NSError+GRPC.m b/src/objective-c/GRPCClient/private/NSError+GRPC.m
index 6ba7235..74cfa94 100644
--- a/src/objective-c/GRPCClient/private/NSError+GRPC.m
+++ b/src/objective-c/GRPCClient/private/NSError+GRPC.m
@@ -20,7 +20,7 @@
#include <grpc/grpc.h>
-NSString * const kGRPCErrorDomain = @"io.grpc";
+NSString *const kGRPCErrorDomain = @"io.grpc";
@implementation NSError (GRPC)
+ (instancetype)grpc_errorFromStatusCode:(grpc_status_code)statusCode details:(char *)details {
@@ -30,6 +30,6 @@
NSString *message = [NSString stringWithCString:details encoding:NSASCIIStringEncoding];
return [NSError errorWithDomain:kGRPCErrorDomain
code:statusCode
- userInfo:@{NSLocalizedDescriptionKey: message}];
+ userInfo:@{NSLocalizedDescriptionKey : message}];
}
@end
diff --git a/src/objective-c/GRPCClient/private/version.h b/src/objective-c/GRPCClient/private/version.h
index 405c2ff..6fe4a7d 100644
--- a/src/objective-c/GRPCClient/private/version.h
+++ b/src/objective-c/GRPCClient/private/version.h
@@ -22,5 +22,4 @@
// instead. This file can be regenerated from the template by running
// `tools/buildgen/generate_projects.sh`.
-
-#define GRPC_OBJC_VERSION_STRING @"1.11.0-dev"
+#define GRPC_OBJC_VERSION_STRING @"1.13.0-dev"
diff --git a/src/objective-c/ProtoRPC/ProtoMethod.h b/src/objective-c/ProtoRPC/ProtoMethod.h
index 227154c..3ba0f70 100644
--- a/src/objective-c/ProtoRPC/ProtoMethod.h
+++ b/src/objective-c/ProtoRPC/ProtoMethod.h
@@ -22,9 +22,8 @@
* A fully-qualified proto service method name. Full qualification is needed because a gRPC endpoint
* can implement multiple services.
*/
-__attribute__((deprecated("Please use GRPCProtoMethod.")))
-@interface ProtoMethod : NSObject
-@property(nonatomic, readonly) NSString *package;
+__attribute__((deprecated("Please use GRPCProtoMethod."))) @interface ProtoMethod
+ : NSObject @property(nonatomic, readonly) NSString *package;
@property(nonatomic, readonly) NSString *service;
@property(nonatomic, readonly) NSString *method;
@@ -41,7 +40,7 @@
*/
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
-@interface GRPCProtoMethod : ProtoMethod
+ @interface GRPCProtoMethod : ProtoMethod
#pragma clang diagnostic pop
-@end
+ @end
diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h
index 2546edc..45d3526 100644
--- a/src/objective-c/ProtoRPC/ProtoRPC.h
+++ b/src/objective-c/ProtoRPC/ProtoRPC.h
@@ -21,18 +21,18 @@
#import "ProtoMethod.h"
-__attribute__((deprecated("Please use GRPCProtoCall.")))
-@interface ProtoRPC : GRPCCall
+__attribute__((deprecated("Please use GRPCProtoCall."))) @interface ProtoRPC
+ : GRPCCall
-/**
- * host parameter should not contain the scheme (http:// or https://), only the name or IP addr
- * and the port number, for example @"localhost:5050".
- */
-- (instancetype)initWithHost:(NSString *)host
- method:(GRPCProtoMethod *)method
- requestsWriter:(GRXWriter *)requestsWriter
- responseClass:(Class)responseClass
- responsesWriteable:(id<GRXWriteable>)responsesWriteable NS_DESIGNATED_INITIALIZER;
+ /**
+ * host parameter should not contain the scheme (http:// or https://), only the name or IP
+ * addr and the port number, for example @"localhost:5050".
+ */
+ -
+ (instancetype)initWithHost : (NSString *)host method
+ : (GRPCProtoMethod *)method requestsWriter : (GRXWriter *)requestsWriter responseClass
+ : (Class)responseClass responsesWriteable
+ : (id<GRXWriteable>)responsesWriteable NS_DESIGNATED_INITIALIZER;
- (void)start;
@end
@@ -43,7 +43,7 @@
*/
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
-@interface GRPCProtoCall : ProtoRPC
+ @interface GRPCProtoCall : ProtoRPC
#pragma clang diagnostic pop
-@end
+ @end
diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m
index 20b9d04..5dca971 100644
--- a/src/objective-c/ProtoRPC/ProtoRPC.m
+++ b/src/objective-c/ProtoRPC/ProtoRPC.m
@@ -19,27 +19,26 @@
#import "ProtoRPC.h"
#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS
- #import <Protobuf/GPBProtocolBuffers.h>
+#import <Protobuf/GPBProtocolBuffers.h>
#else
- #import <GPBProtocolBuffers.h>
+#import <GPBProtocolBuffers.h>
#endif
#import <RxLibrary/GRXWriteable.h>
#import <RxLibrary/GRXWriter+Transformations.h>
static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsingError) {
NSDictionary *info = @{
- NSLocalizedDescriptionKey: @"Unable to parse response from the server",
- NSLocalizedRecoverySuggestionErrorKey: @"If this RPC is idempotent, retry "
- @"with exponential backoff. Otherwise, query the server status before "
- @"retrying.",
- NSUnderlyingErrorKey: parsingError,
- @"Expected class": expectedClass,
- @"Received value": proto,
- };
+ NSLocalizedDescriptionKey : @"Unable to parse response from the server",
+ NSLocalizedRecoverySuggestionErrorKey :
+ @"If this RPC is idempotent, retry "
+ @"with exponential backoff. Otherwise, query the server status before "
+ @"retrying.",
+ NSUnderlyingErrorKey : parsingError,
+ @"Expected class" : expectedClass,
+ @"Received value" : proto,
+ };
// TODO(jcanizales): Use kGRPCErrorDomain and GRPCErrorCodeInternal when they're public.
- return [NSError errorWithDomain:@"io.grpc"
- code:13
- userInfo:info];
+ return [NSError errorWithDomain:@"io.grpc" code:13 userInfo:info];
}
#pragma clang diagnostic push
@@ -92,9 +91,10 @@
} else {
[weakSelf finishWithError:ErrorForBadProto(value, responseClass, error)];
}
- } completionHandler:^(NSError *errorOrNil) {
- [responsesWriteable writesFinishedWithError:errorOrNil];
- }];
+ }
+ completionHandler:^(NSError *errorOrNil) {
+ [responsesWriteable writesFinishedWithError:errorOrNil];
+ }];
}
return self;
}
diff --git a/src/objective-c/ProtoRPC/ProtoService.h b/src/objective-c/ProtoRPC/ProtoService.h
index 3537896..29c4e9b 100644
--- a/src/objective-c/ProtoRPC/ProtoService.h
+++ b/src/objective-c/ProtoRPC/ProtoService.h
@@ -22,27 +22,24 @@
@protocol GRXWriteable;
@class GRXWriter;
-
-__attribute__((deprecated("Please use GRPCProtoService.")))
-@interface ProtoService : NSObject
-- (instancetype)initWithHost:(NSString *)host
- packageName:(NSString *)packageName
- serviceName:(NSString *)serviceName NS_DESIGNATED_INITIALIZER;
+__attribute__((deprecated("Please use GRPCProtoService."))) @interface ProtoService
+ : NSObject -
+ (instancetype)initWithHost : (NSString *)host packageName
+ : (NSString *)packageName serviceName : (NSString *)serviceName NS_DESIGNATED_INITIALIZER;
- (GRPCProtoCall *)RPCToMethod:(NSString *)method
- requestsWriter:(GRXWriter *)requestsWriter
- responseClass:(Class)responseClass
- responsesWriteable:(id<GRXWriteable>)responsesWriteable;
+ requestsWriter:(GRXWriter *)requestsWriter
+ responseClass:(Class)responseClass
+ responsesWriteable:(id<GRXWriteable>)responsesWriteable;
@end
-
/**
* This subclass is empty now. Eventually we'll remove ProtoService class
* to avoid potential naming conflict
*/
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
-@interface GRPCProtoService : ProtoService
+ @interface GRPCProtoService : ProtoService
#pragma clang diagnostic pop
-@end
+ @end
diff --git a/src/objective-c/ProtoRPC/ProtoService.m b/src/objective-c/ProtoRPC/ProtoService.m
index 611cee4..3e9cc5c 100644
--- a/src/objective-c/ProtoRPC/ProtoService.m
+++ b/src/objective-c/ProtoRPC/ProtoService.m
@@ -57,9 +57,8 @@
requestsWriter:(GRXWriter *)requestsWriter
responseClass:(Class)responseClass
responsesWriteable:(id<GRXWriteable>)responsesWriteable {
- GRPCProtoMethod *methodName = [[GRPCProtoMethod alloc] initWithPackage:_packageName
- service:_serviceName
- method:method];
+ GRPCProtoMethod *methodName =
+ [[GRPCProtoMethod alloc] initWithPackage:_packageName service:_serviceName method:method];
return [[GRPCProtoCall alloc] initWithHost:_host
method:methodName
requestsWriter:requestsWriter
diff --git a/src/objective-c/RxLibrary/GRXBufferedPipe.m b/src/objective-c/RxLibrary/GRXBufferedPipe.m
index 577a5e9..546d46c 100644
--- a/src/objective-c/RxLibrary/GRXBufferedPipe.m
+++ b/src/objective-c/RxLibrary/GRXBufferedPipe.m
@@ -67,7 +67,7 @@
#pragma mark GRXWriter implementation
- (void)setState:(GRXWriterState)newState {
- @synchronized (self) {
+ @synchronized(self) {
// Manual transitions are only allowed from the started or paused states.
if (_state == GRXWriterStateNotStarted || _state == GRXWriterStateFinished) {
return;
@@ -112,8 +112,7 @@
- (void)dealloc {
GRXWriterState state = self.state;
- if (state == GRXWriterStateNotStarted ||
- state == GRXWriterStatePaused) {
+ if (state == GRXWriterStateNotStarted || state == GRXWriterStatePaused) {
dispatch_resume(_writeQueue);
}
}
diff --git a/src/objective-c/RxLibrary/GRXConcurrentWriteable.h b/src/objective-c/RxLibrary/GRXConcurrentWriteable.h
index f16a3d0..abb831e 100644
--- a/src/objective-c/RxLibrary/GRXConcurrentWriteable.h
+++ b/src/objective-c/RxLibrary/GRXConcurrentWriteable.h
@@ -18,8 +18,8 @@
#import <Foundation/Foundation.h>
-#import "GRXWriter.h"
#import "GRXWriteable.h"
+#import "GRXWriter.h"
/**
* This is a thread-safe wrapper over a GRXWriteable instance. It lets one enqueue calls to a
diff --git a/src/objective-c/RxLibrary/GRXConcurrentWriteable.m b/src/objective-c/RxLibrary/GRXConcurrentWriteable.m
index c262313..523c59c 100644
--- a/src/objective-c/RxLibrary/GRXConcurrentWriteable.m
+++ b/src/objective-c/RxLibrary/GRXConcurrentWriteable.m
@@ -46,8 +46,7 @@
}
- (instancetype)initWithWriteable:(id<GRXWriteable>)writeable {
- return [self initWithWriteable:writeable
- dispatchQueue:dispatch_get_main_queue()];
+ return [self initWithWriteable:writeable dispatchQueue:dispatch_get_main_queue()];
}
- (void)enqueueValue:(id)value completionHandler:(void (^)(void))handler {
@@ -69,7 +68,7 @@
typeof(self) strongSelf = weakSelf;
if (strongSelf) {
BOOL finished = NO;
- @synchronized (self) {
+ @synchronized(self) {
if (!strongSelf->_alreadyFinished) {
strongSelf->_alreadyFinished = YES;
} else {
@@ -90,7 +89,7 @@
- (void)cancelWithError:(NSError *)error {
NSAssert(error, @"For a successful completion, use enqueueSuccessfulCompletion.");
BOOL finished = NO;
- @synchronized (self) {
+ @synchronized(self) {
if (!_alreadyFinished) {
_alreadyFinished = YES;
} else {
@@ -112,7 +111,7 @@
- (void)cancelSilently {
BOOL finished = NO;
- @synchronized (self) {
+ @synchronized(self) {
if (!_alreadyFinished) {
_alreadyFinished = YES;
} else {
diff --git a/src/objective-c/RxLibrary/GRXForwardingWriter.m b/src/objective-c/RxLibrary/GRXForwardingWriter.m
index e7365d3..3e522ef 100644
--- a/src/objective-c/RxLibrary/GRXForwardingWriter.m
+++ b/src/objective-c/RxLibrary/GRXForwardingWriter.m
@@ -18,7 +18,7 @@
#import "GRXForwardingWriter.h"
-@interface GRXForwardingWriter () <GRXWriteable>
+@interface GRXForwardingWriter ()<GRXWriteable>
@end
@implementation GRXForwardingWriter {
diff --git a/src/objective-c/RxLibrary/GRXImmediateWriter.m b/src/objective-c/RxLibrary/GRXImmediateWriter.m
index c5d6d13..0456961 100644
--- a/src/objective-c/RxLibrary/GRXImmediateWriter.m
+++ b/src/objective-c/RxLibrary/GRXImmediateWriter.m
@@ -28,8 +28,8 @@
@synthesize state = _state;
-- (instancetype) init {
- return [self initWithEnumerator:nil error:nil]; // results in an empty writer.
+- (instancetype)init {
+ return [self initWithEnumerator:nil error:nil]; // results in an empty writer.
}
// Designated initializer
@@ -57,7 +57,8 @@
}
+ (GRXWriter *)writerWithContainer:(id<NSFastEnumeration>)container {
- return [self writerWithEnumerator:[NSEnumerator grx_enumeratorWithContainer:container]];;
+ return [self writerWithEnumerator:[NSEnumerator grx_enumeratorWithContainer:container]];
+ ;
}
+ (GRXWriter *)writerWithValue:(id)value {
diff --git a/src/objective-c/RxLibrary/GRXWriteable.h b/src/objective-c/RxLibrary/GRXWriteable.h
index d150bc8..71b5979 100644
--- a/src/objective-c/RxLibrary/GRXWriteable.h
+++ b/src/objective-c/RxLibrary/GRXWriteable.h
@@ -22,7 +22,7 @@
* A GRXWriteable is an object to which a sequence of values can be sent. The
* sequence finishes with an optional error.
*/
-@protocol GRXWriteable <NSObject>
+@protocol GRXWriteable<NSObject>
/** Push the next value of the sequence to the receiving object. */
- (void)writeValue:(id)value;
diff --git a/src/objective-c/RxLibrary/GRXWriteable.m b/src/objective-c/RxLibrary/GRXWriteable.m
index fcdf3ba..e6c4c81 100644
--- a/src/objective-c/RxLibrary/GRXWriteable.m
+++ b/src/objective-c/RxLibrary/GRXWriteable.m
@@ -42,9 +42,8 @@
} else if (error) {
singleHandler(nil, error);
} else {
- NSDictionary *userInfo = @{
- NSLocalizedDescriptionKey: @"The writer finished without producing any value."
- };
+ NSDictionary *userInfo =
+ @{NSLocalizedDescriptionKey : @"The writer finished without producing any value."};
// Even though RxLibrary is independent of gRPC, the domain and code here are, for the moment,
// set to the values of kGRPCErrorDomain and GRPCErrorCodeInternal. This way, the error formed
// is the one user of gRPC would expect if the server failed to produce a response.
@@ -55,9 +54,9 @@
// the two domains.
static NSString *kGRPCErrorDomain = @"io.grpc";
static NSUInteger kGRPCErrorCodeInternal = 13;
- singleHandler(nil, [NSError errorWithDomain:kGRPCErrorDomain
- code:kGRPCErrorCodeInternal
- userInfo:userInfo]);
+ singleHandler(
+ nil,
+ [NSError errorWithDomain:kGRPCErrorDomain code:kGRPCErrorCodeInternal userInfo:userInfo]);
}
};
return [self writeableWithEventHandler:^(BOOL done, id value, NSError *error) {
@@ -73,9 +72,10 @@
}
return [[self alloc] initWithValueHandler:^(id value) {
handler(NO, value, nil);
- } completionHandler:^(NSError *errorOrNil) {
- handler(YES, nil, errorOrNil);
- }];
+ }
+ completionHandler:^(NSError *errorOrNil) {
+ handler(YES, nil, errorOrNil);
+ }];
}
- (instancetype)init {
diff --git a/src/objective-c/RxLibrary/GRXWriter+Immediate.m b/src/objective-c/RxLibrary/GRXWriter+Immediate.m
index a36a567..58cd8dd 100644
--- a/src/objective-c/RxLibrary/GRXWriter+Immediate.m
+++ b/src/objective-c/RxLibrary/GRXWriter+Immediate.m
@@ -18,8 +18,8 @@
#import "GRXWriter+Immediate.h"
-#import "GRXImmediateWriter.h"
#import "GRXImmediateSingleWriter.h"
+#import "GRXImmediateWriter.h"
@implementation GRXWriter (Immediate)
diff --git a/src/objective-c/RxLibrary/transformations/GRXMappingWriter.h b/src/objective-c/RxLibrary/transformations/GRXMappingWriter.h
index 39fe7e1..a344f96 100644
--- a/src/objective-c/RxLibrary/transformations/GRXMappingWriter.h
+++ b/src/objective-c/RxLibrary/transformations/GRXMappingWriter.h
@@ -18,8 +18,9 @@
#import "RxLibrary/GRXForwardingWriter.h"
-/** A "proxy" writer that transforms all the values of its input writer by using a mapping function. */
+/** A "proxy" writer that transforms all the values of its input writer by using a mapping function.
+ */
@interface GRXMappingWriter : GRXForwardingWriter
-- (instancetype)initWithWriter:(GRXWriter *)writer map:(id (^)(id value))map
- NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithWriter:(GRXWriter *)writer
+ map:(id (^)(id value))map NS_DESIGNATED_INITIALIZER;
@end
diff --git a/src/objective-c/RxLibrary/transformations/GRXMappingWriter.m b/src/objective-c/RxLibrary/transformations/GRXMappingWriter.m
index baad4ab..108ed86 100644
--- a/src/objective-c/RxLibrary/transformations/GRXMappingWriter.m
+++ b/src/objective-c/RxLibrary/transformations/GRXMappingWriter.m
@@ -18,7 +18,7 @@
#import "GRXMappingWriter.h"
-@interface GRXForwardingWriter () <GRXWriteable>
+@interface GRXForwardingWriter ()<GRXWriteable>
@end
@implementation GRXMappingWriter {
diff --git a/src/objective-c/examples/Sample/Sample/AppDelegate.h b/src/objective-c/examples/Sample/Sample/AppDelegate.h
index c345a54..2707c8b 100644
--- a/src/objective-c/examples/Sample/Sample/AppDelegate.h
+++ b/src/objective-c/examples/Sample/Sample/AppDelegate.h
@@ -18,6 +18,6 @@
#import <UIKit/UIKit.h>
-@interface AppDelegate : UIResponder <UIApplicationDelegate>
-@property (strong, nonatomic) UIWindow *window;
+@interface AppDelegate : UIResponder<UIApplicationDelegate>
+@property(strong, nonatomic) UIWindow* window;
@end
diff --git a/src/objective-c/examples/Sample/Sample/ViewController.m b/src/objective-c/examples/Sample/Sample/ViewController.m
index a0778df..9bcb002 100644
--- a/src/objective-c/examples/Sample/Sample/ViewController.m
+++ b/src/objective-c/examples/Sample/Sample/ViewController.m
@@ -22,15 +22,15 @@
#import <ProtoRPC/ProtoMethod.h>
#import <RemoteTest/Messages.pbobjc.h>
#import <RemoteTest/Test.pbrpc.h>
-#import <RxLibrary/GRXWriter+Immediate.h>
#import <RxLibrary/GRXWriteable.h>
+#import <RxLibrary/GRXWriter+Immediate.h>
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
- NSString * const kRemoteHost = @"grpc-test.sandbox.googleapis.com";
+ NSString *const kRemoteHost = @"grpc-test.sandbox.googleapis.com";
RMTSimpleRequest *request = [[RMTSimpleRequest alloc] init];
request.responseSize = 10;
@@ -40,14 +40,14 @@
// Example gRPC call using a generated proto client library:
RMTTestService *service = [[RMTTestService alloc] initWithHost:kRemoteHost];
- [service unaryCallWithRequest:request handler:^(RMTSimpleResponse *response, NSError *error) {
- if (response) {
- NSLog(@"Finished successfully with response:\n%@", response);
- } else if (error) {
- NSLog(@"Finished with error: %@", error);
- }
- }];
-
+ [service unaryCallWithRequest:request
+ handler:^(RMTSimpleResponse *response, NSError *error) {
+ if (response) {
+ NSLog(@"Finished successfully with response:\n%@", response);
+ } else if (error) {
+ NSLog(@"Finished with error: %@", error);
+ }
+ }];
// Same example call using the generic gRPC client library:
@@ -61,16 +61,18 @@
path:method.HTTPPath
requestsWriter:requestsWriter];
- id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
- RMTSimpleResponse *response = [RMTSimpleResponse parseFromData:value error:NULL];
- NSLog(@"Received response:\n%@", response);
- } completionHandler:^(NSError *errorOrNil) {
- if (errorOrNil) {
- NSLog(@"Finished with error: %@", errorOrNil);
- } else {
- NSLog(@"Finished successfully.");
- }
- }];
+ id<GRXWriteable> responsesWriteable =
+ [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
+ RMTSimpleResponse *response = [RMTSimpleResponse parseFromData:value error:NULL];
+ NSLog(@"Received response:\n%@", response);
+ }
+ completionHandler:^(NSError *errorOrNil) {
+ if (errorOrNil) {
+ NSLog(@"Finished with error: %@", errorOrNil);
+ } else {
+ NSLog(@"Finished successfully.");
+ }
+ }];
[call startWithWriteable:responsesWriteable];
}
diff --git a/src/objective-c/examples/Sample/Sample/main.m b/src/objective-c/examples/Sample/Sample/main.m
index aa89f7b..852f55f 100644
--- a/src/objective-c/examples/Sample/Sample/main.m
+++ b/src/objective-c/examples/Sample/Sample/main.m
@@ -19,8 +19,8 @@
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
-int main(int argc, char * argv[]) {
+int main(int argc, char* argv[]) {
@autoreleasepool {
- return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
+ return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
diff --git a/src/objective-c/examples/SwiftSample/SwiftSample.xcodeproj/project.pbxproj b/src/objective-c/examples/SwiftSample/SwiftSample.xcodeproj/project.pbxproj
index 6247d0b..0113d9c 100644
--- a/src/objective-c/examples/SwiftSample/SwiftSample.xcodeproj/project.pbxproj
+++ b/src/objective-c/examples/SwiftSample/SwiftSample.xcodeproj/project.pbxproj
@@ -168,13 +168,16 @@
files = (
);
inputPaths = (
+ "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+ "${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputPaths = (
+ "$(DERIVED_FILE_DIR)/Pods-SwiftSample-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
+ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
A1738A987353B0BF2C64F0F7 /* [CP] Embed Pods Frameworks */ = {
@@ -183,9 +186,26 @@
files = (
);
inputPaths = (
+ "${SRCROOT}/Pods/Target Support Files/Pods-SwiftSample/Pods-SwiftSample-frameworks.sh",
+ "${BUILT_PRODUCTS_DIR}/BoringSSL/openssl.framework",
+ "${BUILT_PRODUCTS_DIR}/Protobuf/Protobuf.framework",
+ "${BUILT_PRODUCTS_DIR}/RemoteTest/RemoteTest.framework",
+ "${BUILT_PRODUCTS_DIR}/gRPC/GRPCClient.framework",
+ "${BUILT_PRODUCTS_DIR}/gRPC-Core/grpc.framework",
+ "${BUILT_PRODUCTS_DIR}/gRPC-ProtoRPC/ProtoRPC.framework",
+ "${BUILT_PRODUCTS_DIR}/gRPC-RxLibrary/RxLibrary.framework",
+ "${BUILT_PRODUCTS_DIR}/nanopb/nanopb.framework",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/openssl.framework",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Protobuf.framework",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RemoteTest.framework",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GRPCClient.framework",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/grpc.framework",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ProtoRPC.framework",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RxLibrary.framework",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/nanopb.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
@@ -329,7 +349,7 @@
PRODUCT_BUNDLE_IDENTIFIER = "io.grpc.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "";
- SWIFT_VERSION = 2.3;
+ SWIFT_VERSION = 4.0;
USER_HEADER_SEARCH_PATHS = "";
};
name = Debug;
@@ -344,7 +364,7 @@
PRODUCT_BUNDLE_IDENTIFIER = "io.grpc.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "";
- SWIFT_VERSION = 2.3;
+ SWIFT_VERSION = 4.0;
USER_HEADER_SEARCH_PATHS = "";
};
name = Release;
diff --git a/src/objective-c/examples/SwiftSample/ViewController.swift b/src/objective-c/examples/SwiftSample/ViewController.swift
index 5931914..0ba6e21 100644
--- a/src/objective-c/examples/SwiftSample/ViewController.swift
+++ b/src/objective-c/examples/SwiftSample/ViewController.swift
@@ -36,7 +36,7 @@
// Example gRPC call using a generated proto client library:
let service = RMTTestService(host: RemoteHost)
- service.unaryCallWithRequest(request) { response, error in
+ service.unaryCall(with: request) { response, error in
if let response = response {
NSLog("1. Finished successfully with response:\n\(response)")
} else {
@@ -48,7 +48,7 @@
// Same but manipulating headers:
var RPC : GRPCProtoCall! // Needed to convince Swift to capture by reference (__block)
- RPC = service.RPCToUnaryCallWithRequest(request) { response, error in
+ RPC = service.rpcToUnaryCall(with: request) { response, error in
if let response = response {
NSLog("2. Finished successfully with response:\n\(response)")
} else {
@@ -59,23 +59,23 @@
}
// TODO(jcanizales): Revert to using subscript syntax once XCode 8 is released.
- RPC.requestHeaders.setObject("My value", forKey: "My-Header")
+ RPC.requestHeaders["My-Header"] = "My value"
RPC.start()
// Same example call using the generic gRPC client library:
- let method = GRPCProtoMethod(package: "grpc.testing", service: "TestService", method: "UnaryCall")
+ let method = GRPCProtoMethod(package: "grpc.testing", service: "TestService", method: "UnaryCall")!
let requestsWriter = GRXWriter(value: request.data())
- let call = GRPCCall(host: RemoteHost, path: method.HTTPPath, requestsWriter: requestsWriter)
+ let call = GRPCCall(host: RemoteHost, path: method.httpPath, requestsWriter: requestsWriter)!
- call.requestHeaders.setObject("My value", forKey: "My-Header")
+ call.requestHeaders["My-Header"] = "My value"
- call.startWithWriteable(GRXWriteable { response, error in
- if let response = response as? NSData {
+ call.start(with: GRXWriteable { response, error in
+ if let response = response as? Data {
NSLog("3. Received response:\n\(try! RMTSimpleResponse(data: response))")
} else {
NSLog("3. Finished with error: \(error!)")
diff --git a/src/objective-c/tests/Connectivity/ConnectivityTestingApp/ViewController.m b/src/objective-c/tests/Connectivity/ConnectivityTestingApp/ViewController.m
index f91d2a6..88780e3 100644
--- a/src/objective-c/tests/Connectivity/ConnectivityTestingApp/ViewController.m
+++ b/src/objective-c/tests/Connectivity/ConnectivityTestingApp/ViewController.m
@@ -20,9 +20,9 @@
#import <GRPCClient/GRPCCall.h>
#import <ProtoRPC/ProtoMethod.h>
+#import <RxLibrary/GRXBufferedPipe.h>
#import <RxLibrary/GRXWriter+Immediate.h>
#import <RxLibrary/GRXWriter+Transformations.h>
-#import <RxLibrary/GRXBufferedPipe.h>
#import "src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.h"
@@ -35,8 +35,7 @@
- (void)viewDidLoad {
[super viewDidLoad];
- [GRPCConnectivityMonitor registerObserver:self
- selector:@selector(reachabilityChanged:)];
+ [GRPCConnectivityMonitor registerObserver:self selector:@selector(reachabilityChanged:)];
}
- (void)reachabilityChanged:(NSNotification *)note {
@@ -52,23 +51,21 @@
GRPCProtoMethod *method = [[GRPCProtoMethod alloc] initWithPackage:@"grpc.testing"
service:@"TestService"
method:@"UnaryCall"];
- GRXWriter *loggingRequestWriter =
- [[GRXWriter writerWithValue:[NSData dataWithBytes:bytes length:sizeof(bytes)]]
- map:^id(id value) {
- NSLog(@"Sending request.");
- return value;
- }];
- GRPCCall *call = [[GRPCCall alloc] initWithHost:host
- path:method.HTTPPath
- requestsWriter:loggingRequestWriter];
+ GRXWriter *loggingRequestWriter = [[GRXWriter
+ writerWithValue:[NSData dataWithBytes:bytes length:sizeof(bytes)]] map:^id(id value) {
+ NSLog(@"Sending request.");
+ return value;
+ }];
+ GRPCCall *call =
+ [[GRPCCall alloc] initWithHost:host path:method.HTTPPath requestsWriter:loggingRequestWriter];
- [call startWithWriteable:[GRXWriteable writeableWithEventHandler:^(BOOL done, id value,
- NSError *error) {
- if (!done) {
- return;
- }
- NSLog(@"Unary call finished with error: %@", error);
- }]];
+ [call startWithWriteable:[GRXWriteable
+ writeableWithEventHandler:^(BOOL done, id value, NSError *error) {
+ if (!done) {
+ return;
+ }
+ NSLog(@"Unary call finished with error: %@", error);
+ }]];
}
- (IBAction)tapStreaming:(id)sender {
@@ -85,17 +82,16 @@
[requestsBuffer writeValue:[NSData dataWithBytes:bytes length:sizeof(bytes)]];
- GRPCCall *call = [[GRPCCall alloc] initWithHost:host
- path:method.HTTPPath
- requestsWriter:requestsBuffer];
+ GRPCCall *call =
+ [[GRPCCall alloc] initWithHost:host path:method.HTTPPath requestsWriter:requestsBuffer];
- [call startWithWriteable:[GRXWriteable writeableWithEventHandler:^(BOOL done, id value,
- NSError *error) {
- if (!done) {
- return;
- }
- NSLog(@"Streaming call finished with error: %@", error);
- }]];
+ [call startWithWriteable:[GRXWriteable
+ writeableWithEventHandler:^(BOOL done, id value, NSError *error) {
+ if (!done) {
+ return;
+ }
+ NSLog(@"Streaming call finished with error: %@", error);
+ }]];
}
@end
diff --git a/src/objective-c/tests/Connectivity/ConnectivityTestingApp/main.m b/src/objective-c/tests/Connectivity/ConnectivityTestingApp/main.m
index 1642fdb..010789e 100644
--- a/src/objective-c/tests/Connectivity/ConnectivityTestingApp/main.m
+++ b/src/objective-c/tests/Connectivity/ConnectivityTestingApp/main.m
@@ -18,14 +18,14 @@
#import <UIKit/UIKit.h>
-@interface AppDelegate : UIResponder <UIApplicationDelegate>
-@property (strong, nonatomic) UIWindow *window;
+@interface AppDelegate : UIResponder<UIApplicationDelegate>
+@property(strong, nonatomic) UIWindow *window;
@end
@implementation AppDelegate
@end
-int main(int argc, char * argv[]) {
+int main(int argc, char *argv[]) {
@autoreleasepool {
- return UIApplicationMain(argc, argv, nil, NSStringFromClass(AppDelegate.class));
+ return UIApplicationMain(argc, argv, nil, NSStringFromClass(AppDelegate.class));
}
}
diff --git a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm
index 33ccdb5..80fa0f4 100644
--- a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm
+++ b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm
@@ -37,11 +37,11 @@
#include <grpc/support/log.h>
#include "src/core/lib/channel/channel_args.h"
-#include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gpr/tmpfile.h"
+#include "src/core/lib/security/credentials/credentials.h"
#include "test/core/end2end/data/ssl_test_data.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
@@ -58,7 +58,7 @@
grpc_end2end_test_fixture f;
int port = grpc_pick_unused_port_or_die();
fullstack_secure_fixture_data *ffd =
- (fullstack_secure_fixture_data*)gpr_malloc(sizeof(fullstack_secure_fixture_data));
+ (fullstack_secure_fixture_data *)gpr_malloc(sizeof(fullstack_secure_fixture_data));
memset(&f, 0, sizeof(f));
gpr_join_host_port(&ffd->localaddr, "127.0.0.1", port);
@@ -70,9 +70,8 @@
return f;
}
-static void process_auth_failure(void *state, grpc_auth_context *ctx,
- const grpc_metadata *md, size_t md_count,
- grpc_process_auth_metadata_done_cb cb,
+static void process_auth_failure(void *state, grpc_auth_context *ctx, const grpc_metadata *md,
+ size_t md_count, grpc_process_auth_metadata_done_cb cb,
void *user_data) {
GPR_ASSERT(state == NULL);
cb(user_data, NULL, 0, NULL, 0, GRPC_STATUS_UNAUTHENTICATED, NULL);
@@ -82,22 +81,26 @@
grpc_channel_args *client_args,
stream_engine *cronetEngine) {
fullstack_secure_fixture_data *ffd = (fullstack_secure_fixture_data *)f->fixture_data;
- f->client = grpc_cronet_secure_channel_create(cronetEngine, ffd->localaddr,
- client_args, NULL);
+ grpc_arg arg;
+ arg.key = const_cast<char *>(GRPC_ARG_DISABLE_CLIENT_AUTHORITY_FILTER);
+ arg.type = GRPC_ARG_INTEGER;
+ arg.value.integer = 1;
+ client_args = grpc_channel_args_copy_and_add(client_args, &arg, 1);
+ f->client = grpc_cronet_secure_channel_create(cronetEngine, ffd->localaddr, client_args, NULL);
+ grpc_channel_args_destroy(client_args);
GPR_ASSERT(f->client != NULL);
}
-static void chttp2_init_server_secure_fullstack(
- grpc_end2end_test_fixture *f, grpc_channel_args *server_args,
- grpc_server_credentials *server_creds) {
+static void chttp2_init_server_secure_fullstack(grpc_end2end_test_fixture *f,
+ grpc_channel_args *server_args,
+ grpc_server_credentials *server_creds) {
fullstack_secure_fixture_data *ffd = (fullstack_secure_fixture_data *)f->fixture_data;
if (f->server) {
grpc_server_destroy(f->server);
}
f->server = grpc_server_create(server_args, NULL);
grpc_server_register_completion_queue(f->server, f->cq, NULL);
- GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr,
- server_creds));
+ GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, server_creds));
grpc_server_credentials_release(server_creds);
grpc_server_start(f->server);
}
@@ -108,8 +111,8 @@
gpr_free(ffd);
}
-static void cronet_init_client_simple_ssl_secure_fullstack(
- grpc_end2end_test_fixture *f, grpc_channel_args *client_args) {
+static void cronet_init_client_simple_ssl_secure_fullstack(grpc_end2end_test_fixture *f,
+ grpc_channel_args *client_args) {
grpc_core::ExecCtx exec_ctx;
stream_engine *cronetEngine = [Cronet getGlobalEngine];
@@ -122,18 +125,16 @@
size_t i;
if (server_args == NULL) return 0;
for (i = 0; i < server_args->num_args; i++) {
- if (strcmp(server_args->args[i].key, FAIL_AUTH_CHECK_SERVER_ARG_NAME) ==
- 0) {
+ if (strcmp(server_args->args[i].key, FAIL_AUTH_CHECK_SERVER_ARG_NAME) == 0) {
return 1;
}
}
return 0;
}
-static void chttp2_init_server_simple_ssl_secure_fullstack(
- grpc_end2end_test_fixture *f, grpc_channel_args *server_args) {
- grpc_ssl_pem_key_cert_pair pem_cert_key_pair = {test_server1_key,
- test_server1_cert};
+static void chttp2_init_server_simple_ssl_secure_fullstack(grpc_end2end_test_fixture *f,
+ grpc_channel_args *server_args) {
+ grpc_ssl_pem_key_cert_pair pem_cert_key_pair = {test_server1_key, test_server1_cert};
grpc_server_credentials *ssl_creds =
grpc_ssl_server_credentials_create(NULL, &pem_cert_key_pair, 1, 0, NULL);
if (fail_server_auth_check(server_args)) {
@@ -147,12 +148,9 @@
static grpc_end2end_test_config configs[] = {
{"chttp2/simple_ssl_fullstack",
- FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
- FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS,
- chttp2_create_fixture_secure_fullstack,
- cronet_init_client_simple_ssl_secure_fullstack,
- chttp2_init_server_simple_ssl_secure_fullstack,
- chttp2_tear_down_secure_fullstack},
+ FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION | FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS, nullptr,
+ chttp2_create_fixture_secure_fullstack, cronet_init_client_simple_ssl_secure_fullstack,
+ chttp2_init_server_simple_ssl_secure_fullstack, chttp2_tear_down_secure_fullstack},
};
static char *roots_filename;
@@ -186,9 +184,8 @@
[Cronet setHttp2Enabled:YES];
[Cronet enableTestCertVerifierForTesting];
- NSURL *url = [[[NSFileManager defaultManager]
- URLsForDirectory:NSDocumentDirectory
- inDomains:NSUserDomainMask] lastObject];
+ NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory
+ inDomains:NSUserDomainMask] lastObject];
NSLog(@"Documents directory: %@", url);
[Cronet start];
[Cronet startNetLogToFile:@"cronet_netlog.json" logBytes:YES];
diff --git a/src/objective-c/tests/CronetUnitTests/CronetUnitTests.m b/src/objective-c/tests/CronetUnitTests/CronetUnitTests.m
index 28414b8..a6dfb15 100644
--- a/src/objective-c/tests/CronetUnitTests/CronetUnitTests.m
+++ b/src/objective-c/tests/CronetUnitTests/CronetUnitTests.m
@@ -42,8 +42,7 @@
static void drain_cq(grpc_completion_queue *cq) {
grpc_event ev;
do {
- ev = grpc_completion_queue_next(cq, grpc_timeout_seconds_to_deadline(5),
- NULL);
+ ev = grpc_completion_queue_next(cq, grpc_timeout_seconds_to_deadline(5), NULL);
} while (ev.type != GRPC_QUEUE_SHUTDOWN);
}
@@ -64,9 +63,8 @@
[Cronet setHttp2Enabled:YES];
[Cronet setSslKeyLogFileName:@"Documents/key"];
[Cronet enableTestCertVerifierForTesting];
- NSURL *url = [[[NSFileManager defaultManager]
- URLsForDirectory:NSDocumentDirectory
- inDomains:NSUserDomainMask] lastObject];
+ NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory
+ inDomains:NSUserDomainMask] lastObject];
NSLog(@"Documents directory: %@", url);
[Cronet start];
[Cronet startNetLogToFile:@"Documents/cronet_netlog.json" logBytes:YES];
@@ -88,8 +86,8 @@
void cleanup_ssl(void) { EVP_cleanup(); }
-int alpn_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen,
- const unsigned char *in, unsigned int inlen, void *arg) {
+int alpn_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen, const unsigned char *in,
+ unsigned int inlen, void *arg) {
// Always select "h2" as the ALPN protocol to be used
*out = (const unsigned char *)"h2";
*outlen = 2;
@@ -98,16 +96,14 @@
void init_ctx(SSL_CTX *ctx) {
// Install server certificate
- BIO *pem = BIO_new_mem_buf((void *)test_server1_cert,
- (int)strlen(test_server1_cert));
+ BIO *pem = BIO_new_mem_buf((void *)test_server1_cert, (int)strlen(test_server1_cert));
X509 *cert = PEM_read_bio_X509_AUX(pem, NULL, NULL, (char *)"");
SSL_CTX_use_certificate(ctx, cert);
X509_free(cert);
BIO_free(pem);
// Install server private key
- pem =
- BIO_new_mem_buf((void *)test_server1_key, (int)strlen(test_server1_key));
+ pem = BIO_new_mem_buf((void *)test_server1_key, (int)strlen(test_server1_key));
EVP_PKEY *key = PEM_read_bio_PrivateKey(pem, NULL, NULL, (char *)"");
SSL_CTX_use_PrivateKey(ctx, key);
EVP_PKEY_free(key);
@@ -126,12 +122,18 @@
((unsigned int)(unsigned char)(field[2]));
}
+grpc_channel_args *add_disable_client_authority_filter_args(grpc_channel_args *args) {
+ grpc_arg arg;
+ arg.key = const_cast<char *>(GRPC_ARG_DISABLE_CLIENT_AUTHORITY_FILTER);
+ arg.type = GRPC_ARG_INTEGER;
+ arg.value.integer = 1;
+ return grpc_channel_args_copy_and_add(args, &arg, 1);
+}
+
- (void)testInternalError {
grpc_call *c;
- grpc_slice request_payload_slice =
- grpc_slice_from_copied_string("hello world");
- grpc_byte_buffer *request_payload =
- grpc_raw_byte_buffer_create(&request_payload_slice, 1);
+ grpc_slice request_payload_slice = grpc_slice_from_copied_string("hello world");
+ grpc_byte_buffer *request_payload = grpc_raw_byte_buffer_create(&request_payload_slice, 1);
gpr_timespec deadline = grpc_timeout_seconds_to_deadline(5);
grpc_metadata meta_c[2] = {{grpc_slice_from_static_string("key1"),
grpc_slice_from_static_string("val1"),
@@ -147,8 +149,9 @@
gpr_join_host_port(&addr, "127.0.0.1", port);
grpc_completion_queue *cq = grpc_completion_queue_create_for_next(NULL);
stream_engine *cronetEngine = [Cronet getGlobalEngine];
- grpc_channel *client =
- grpc_cronet_secure_channel_create(cronetEngine, addr, NULL, NULL);
+ grpc_channel_args *client_args = add_disable_client_authority_filter_args(NULL);
+ grpc_channel *client = grpc_cronet_secure_channel_create(cronetEngine, addr, client_args, NULL);
+ grpc_channel_args_destroy(client_args);
cq_verifier *cqv = cq_verifier_create(cq);
grpc_op ops[6];
@@ -163,8 +166,7 @@
grpc_slice details;
c = grpc_channel_create_call(client, NULL, GRPC_PROPAGATE_DEFAULTS, cq,
- grpc_slice_from_static_string("/foo"), NULL,
- deadline, NULL);
+ grpc_slice_from_static_string("/foo"), NULL, deadline, NULL);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
@@ -221,16 +223,15 @@
error = grpc_call_start_batch(c, ops, (size_t)(op - ops), (void *)1, NULL);
GPR_ASSERT(GRPC_CALL_OK == error);
- dispatch_async(
- dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
- int s = accept(sl, NULL, NULL);
- GPR_ASSERT(s >= 0);
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ int s = accept(sl, NULL, NULL);
+ GPR_ASSERT(s >= 0);
- // Close the connection after 1 second to trigger Cronet's on_failed()
- sleep(1);
- close(s);
- close(sl);
- });
+ // Close the connection after 1 second to trigger Cronet's on_failed()
+ sleep(1);
+ close(s);
+ close(sl);
+ });
CQ_EXPECT_COMPLETION(cqv, (void *)1, 1);
cq_verify(cqv);
@@ -262,11 +263,11 @@
arg.type = GRPC_ARG_INTEGER;
arg.value.integer = useCoalescing ? 1 : 0;
grpc_channel_args *args = grpc_channel_args_copy_and_add(NULL, &arg, 1);
+ args = add_disable_client_authority_filter_args(args);
+
grpc_call *c;
- grpc_slice request_payload_slice =
- grpc_slice_from_copied_string("hello world");
- grpc_byte_buffer *request_payload =
- grpc_raw_byte_buffer_create(&request_payload_slice, 1);
+ grpc_slice request_payload_slice = grpc_slice_from_copied_string("hello world");
+ grpc_byte_buffer *request_payload = grpc_raw_byte_buffer_create(&request_payload_slice, 1);
gpr_timespec deadline = grpc_timeout_seconds_to_deadline(5);
grpc_metadata meta_c[2] = {{grpc_slice_from_static_string("key1"),
grpc_slice_from_static_string("val1"),
@@ -282,8 +283,7 @@
gpr_join_host_port(&addr, "127.0.0.1", port);
grpc_completion_queue *cq = grpc_completion_queue_create_for_next(NULL);
stream_engine *cronetEngine = [Cronet getGlobalEngine];
- grpc_channel *client =
- grpc_cronet_secure_channel_create(cronetEngine, addr, args, NULL);
+ grpc_channel *client = grpc_cronet_secure_channel_create(cronetEngine, addr, args, NULL);
cq_verifier *cqv = cq_verifier_create(cq);
grpc_op ops[6];
@@ -298,8 +298,7 @@
grpc_slice details;
c = grpc_channel_create_call(client, NULL, GRPC_PROPAGATE_DEFAULTS, cq,
- grpc_slice_from_static_string("/foo"), NULL,
- deadline, NULL);
+ grpc_slice_from_static_string("/foo"), NULL, deadline, NULL);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
@@ -307,8 +306,7 @@
grpc_metadata_array_init(&request_metadata_recv);
grpc_call_details_init(&call_details);
- __weak XCTestExpectation *expectation =
- [self expectationWithDescription:@"Coalescing"];
+ __weak XCTestExpectation *expectation = [self expectationWithDescription:@"Coalescing"];
int sl = socket(AF_INET, SOCK_STREAM, 0);
GPR_ASSERT(sl >= 0);
@@ -320,61 +318,60 @@
GPR_ASSERT(0 == bind(sl, (struct sockaddr *)&s_addr, sizeof(s_addr)));
GPR_ASSERT(0 == listen(sl, 5));
- dispatch_async(
- dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
- int s = accept(sl, NULL, NULL);
- GPR_ASSERT(s >= 0);
- struct timeval tv;
- tv.tv_sec = 2;
- tv.tv_usec = 0;
- setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ int s = accept(sl, NULL, NULL);
+ GPR_ASSERT(s >= 0);
+ struct timeval tv;
+ tv.tv_sec = 2;
+ tv.tv_usec = 0;
+ setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
- // Make an TLS endpoint to receive Cronet's transmission
- SSL_CTX *ctx = SSL_CTX_new(TLSv1_2_server_method());
- init_ctx(ctx);
- SSL *ssl = SSL_new(ctx);
- SSL_set_fd(ssl, s);
- SSL_accept(ssl);
+ // Make an TLS endpoint to receive Cronet's transmission
+ SSL_CTX *ctx = SSL_CTX_new(TLSv1_2_server_method());
+ init_ctx(ctx);
+ SSL *ssl = SSL_new(ctx);
+ SSL_set_fd(ssl, s);
+ SSL_accept(ssl);
- const char magic[] = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n";
+ const char magic[] = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n";
- char buf[4096];
- long len;
- BOOL coalesced = NO;
- while ((len = SSL_read(ssl, buf, sizeof(buf))) > 0) {
- gpr_log(GPR_DEBUG, "Read len: %ld", len);
+ char buf[4096];
+ long len;
+ BOOL coalesced = NO;
+ while ((len = SSL_read(ssl, buf, sizeof(buf))) > 0) {
+ gpr_log(GPR_DEBUG, "Read len: %ld", len);
- // Analyze the HTTP/2 frames in the same TLS PDU to identify if
- // coalescing is successful
- unsigned int p = 0;
- while (p < len) {
- if (len - p >= 24 && 0 == memcmp(&buf[p], magic, 24)) {
- p += 24;
- continue;
- }
-
- if (buf[p + 3] == 0 && // Type is DATA
- parse_h2_length(&buf[p]) == 0x10 && // Length is correct
- (buf[p + 4] & 1) != 0 && // EOS bit is set
- 0 == memcmp("hello world", &buf[p + 14],
- 11)) { // Message is correct
- coalesced = YES;
- break;
- }
- p += (parse_h2_length(&buf[p]) + 9);
- }
- if (coalesced) {
- break;
- }
+ // Analyze the HTTP/2 frames in the same TLS PDU to identify if
+ // coalescing is successful
+ unsigned int p = 0;
+ while (p < len) {
+ if (len - p >= 24 && 0 == memcmp(&buf[p], magic, 24)) {
+ p += 24;
+ continue;
}
- XCTAssert(coalesced == useCoalescing);
- SSL_free(ssl);
- SSL_CTX_free(ctx);
- close(s);
- close(sl);
- [expectation fulfill];
- });
+ if (buf[p + 3] == 0 && // Type is DATA
+ parse_h2_length(&buf[p]) == 0x10 && // Length is correct
+ (buf[p + 4] & 1) != 0 && // EOS bit is set
+ 0 == memcmp("hello world", &buf[p + 14],
+ 11)) { // Message is correct
+ coalesced = YES;
+ break;
+ }
+ p += (parse_h2_length(&buf[p]) + 9);
+ }
+ if (coalesced) {
+ break;
+ }
+ }
+
+ XCTAssert(coalesced == useCoalescing);
+ SSL_free(ssl);
+ SSL_CTX_free(ctx);
+ close(s);
+ close(sl);
+ [expectation fulfill];
+ });
memset(ops, 0, sizeof(ops));
op = ops;
diff --git a/src/objective-c/tests/GRPCClientTests.m b/src/objective-c/tests/GRPCClientTests.m
index 3bab7f6..5cd0231 100644
--- a/src/objective-c/tests/GRPCClientTests.m
+++ b/src/objective-c/tests/GRPCClientTests.m
@@ -20,25 +20,27 @@
#import <XCTest/XCTest.h>
#import <grpc/grpc.h>
-#import <GRPCClient/GRPCCall.h>
#import <GRPCClient/GRPCCall+ChannelArg.h>
#import <GRPCClient/GRPCCall+OAuth2.h>
#import <GRPCClient/GRPCCall+Tests.h>
+#import <GRPCClient/GRPCCall.h>
#import <GRPCClient/internal_testing/GRPCCall+InternalTests.h>
#import <ProtoRPC/ProtoMethod.h>
#import <RemoteTest/Messages.pbobjc.h>
+#import <RxLibrary/GRXBufferedPipe.h>
#import <RxLibrary/GRXWriteable.h>
#import <RxLibrary/GRXWriter+Immediate.h>
-#import <RxLibrary/GRXBufferedPipe.h>
+
+#include <netinet/in.h>
#import "version.h"
#define TEST_TIMEOUT 16
-static NSString * const kHostAddress = @"localhost:5050";
-static NSString * const kPackage = @"grpc.testing";
-static NSString * const kService = @"TestService";
-static NSString * const kRemoteSSLHost = @"grpc-test.sandbox.googleapis.com";
+static NSString *const kHostAddress = @"localhost:5050";
+static NSString *const kPackage = @"grpc.testing";
+static NSString *const kService = @"TestService";
+static NSString *const kRemoteSSLHost = @"grpc-test.sandbox.googleapis.com";
static GRPCProtoMethod *kInexistentMethod;
static GRPCProtoMethod *kEmptyCallMethod;
@@ -47,15 +49,17 @@
/** Observer class for testing that responseMetadata is KVO-compliant */
@interface PassthroughObserver : NSObject
-- (instancetype) initWithCallback:(void (^)(NSString*, id, NSDictionary*))callback
+- (instancetype)initWithCallback:(void (^)(NSString *, id, NSDictionary *))callback
NS_DESIGNATED_INITIALIZER;
-- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change
+- (void)observeValueForKeyPath:(NSString *)keyPath
+ ofObject:(id)object
+ change:(NSDictionary *)change
context:(void *)context;
@end
@implementation PassthroughObserver {
- void (^_callback)(NSString*, id, NSDictionary*);
+ void (^_callback)(NSString *, id, NSDictionary *);
}
- (instancetype)init {
@@ -82,7 +86,7 @@
@end
-# pragma mark Tests
+#pragma mark Tests
/**
* A few tests similar to InteropTests, but which use the generic gRPC client (GRPCCall) rather than
@@ -106,18 +110,14 @@
[GRPCCall useInsecureConnectionsForHost:kHostAddress];
// This method isn't implemented by the remote server.
- kInexistentMethod = [[GRPCProtoMethod alloc] initWithPackage:kPackage
- service:kService
- method:@"Inexistent"];
- kEmptyCallMethod = [[GRPCProtoMethod alloc] initWithPackage:kPackage
- service:kService
- method:@"EmptyCall"];
- kUnaryCallMethod = [[GRPCProtoMethod alloc] initWithPackage:kPackage
- service:kService
- method:@"UnaryCall"];
- kFullDuplexCallMethod = [[GRPCProtoMethod alloc] initWithPackage:kPackage
- service:kService
- method:@"FullDuplexCall"];
+ kInexistentMethod =
+ [[GRPCProtoMethod alloc] initWithPackage:kPackage service:kService method:@"Inexistent"];
+ kEmptyCallMethod =
+ [[GRPCProtoMethod alloc] initWithPackage:kPackage service:kService method:@"EmptyCall"];
+ kUnaryCallMethod =
+ [[GRPCProtoMethod alloc] initWithPackage:kPackage service:kService method:@"UnaryCall"];
+ kFullDuplexCallMethod =
+ [[GRPCProtoMethod alloc] initWithPackage:kPackage service:kService method:@"FullDuplexCall"];
}
- (void)testConnectionToRemoteServer {
@@ -127,13 +127,15 @@
path:kInexistentMethod.HTTPPath
requestsWriter:[GRXWriter writerWithValue:[NSData data]]];
- id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
- XCTFail(@"Received unexpected response: %@", value);
- } completionHandler:^(NSError *errorOrNil) {
- XCTAssertNotNil(errorOrNil, @"Finished without error!");
- XCTAssertEqual(errorOrNil.code, 12, @"Finished with unexpected error: %@", errorOrNil);
- [expectation fulfill];
- }];
+ id<GRXWriteable> responsesWriteable =
+ [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
+ XCTFail(@"Received unexpected response: %@", value);
+ }
+ completionHandler:^(NSError *errorOrNil) {
+ XCTAssertNotNil(errorOrNil, @"Finished without error!");
+ XCTAssertEqual(errorOrNil.code, 12, @"Finished with unexpected error: %@", errorOrNil);
+ [expectation fulfill];
+ }];
[call startWithWriteable:responsesWriteable];
@@ -141,21 +143,24 @@
}
- (void)testEmptyRPC {
- __weak XCTestExpectation *response = [self expectationWithDescription:@"Empty response received."];
+ __weak XCTestExpectation *response =
+ [self expectationWithDescription:@"Empty response received."];
__weak XCTestExpectation *completion = [self expectationWithDescription:@"Empty RPC completed."];
GRPCCall *call = [[GRPCCall alloc] initWithHost:kHostAddress
path:kEmptyCallMethod.HTTPPath
requestsWriter:[GRXWriter writerWithValue:[NSData data]]];
- id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
- XCTAssertNotNil(value, @"nil value received as response.");
- XCTAssertEqual([value length], 0, @"Non-empty response received: %@", value);
- [response fulfill];
- } completionHandler:^(NSError *errorOrNil) {
- XCTAssertNil(errorOrNil, @"Finished with unexpected error: %@", errorOrNil);
- [completion fulfill];
- }];
+ id<GRXWriteable> responsesWriteable =
+ [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
+ XCTAssertNotNil(value, @"nil value received as response.");
+ XCTAssertEqual([value length], 0, @"Non-empty response received: %@", value);
+ [response fulfill];
+ }
+ completionHandler:^(NSError *errorOrNil) {
+ XCTAssertNil(errorOrNil, @"Finished with unexpected error: %@", errorOrNil);
+ [completion fulfill];
+ }];
[call startWithWriteable:responsesWriteable];
@@ -176,18 +181,20 @@
path:kUnaryCallMethod.HTTPPath
requestsWriter:requestsWriter];
- id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
- XCTAssertNotNil(value, @"nil value received as response.");
- XCTAssertGreaterThan(value.length, 0, @"Empty response received.");
- RMTSimpleResponse *responseProto = [RMTSimpleResponse parseFromData:value error:NULL];
- // We expect empty strings, not nil:
- XCTAssertNotNil(responseProto.username, @"Response's username is nil.");
- XCTAssertNotNil(responseProto.oauthScope, @"Response's OAuth scope is nil.");
- [response fulfill];
- } completionHandler:^(NSError *errorOrNil) {
- XCTAssertNil(errorOrNil, @"Finished with unexpected error: %@", errorOrNil);
- [completion fulfill];
- }];
+ id<GRXWriteable> responsesWriteable =
+ [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
+ XCTAssertNotNil(value, @"nil value received as response.");
+ XCTAssertGreaterThan(value.length, 0, @"Empty response received.");
+ RMTSimpleResponse *responseProto = [RMTSimpleResponse parseFromData:value error:NULL];
+ // We expect empty strings, not nil:
+ XCTAssertNotNil(responseProto.username, @"Response's username is nil.");
+ XCTAssertNotNil(responseProto.oauthScope, @"Response's OAuth scope is nil.");
+ [response fulfill];
+ }
+ completionHandler:^(NSError *errorOrNil) {
+ XCTAssertNil(errorOrNil, @"Finished with unexpected error: %@", errorOrNil);
+ [completion fulfill];
+ }];
[call startWithWriteable:responsesWriteable];
@@ -208,20 +215,22 @@
call.oauth2AccessToken = @"bogusToken";
- id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
- XCTFail(@"Received unexpected response: %@", value);
- } completionHandler:^(NSError *errorOrNil) {
- XCTAssertNotNil(errorOrNil, @"Finished without error!");
- XCTAssertEqual(errorOrNil.code, 16, @"Finished with unexpected error: %@", errorOrNil);
- XCTAssertEqualObjects(call.responseHeaders, errorOrNil.userInfo[kGRPCHeadersKey],
- @"Headers in the NSError object and call object differ.");
- XCTAssertEqualObjects(call.responseTrailers, errorOrNil.userInfo[kGRPCTrailersKey],
- @"Trailers in the NSError object and call object differ.");
- NSString *challengeHeader = call.oauth2ChallengeHeader;
- XCTAssertGreaterThan(challengeHeader.length, 0,
- @"No challenge in response headers %@", call.responseHeaders);
- [expectation fulfill];
- }];
+ id<GRXWriteable> responsesWriteable =
+ [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
+ XCTFail(@"Received unexpected response: %@", value);
+ }
+ completionHandler:^(NSError *errorOrNil) {
+ XCTAssertNotNil(errorOrNil, @"Finished without error!");
+ XCTAssertEqual(errorOrNil.code, 16, @"Finished with unexpected error: %@", errorOrNil);
+ XCTAssertEqualObjects(call.responseHeaders, errorOrNil.userInfo[kGRPCHeadersKey],
+ @"Headers in the NSError object and call object differ.");
+ XCTAssertEqualObjects(call.responseTrailers, errorOrNil.userInfo[kGRPCTrailersKey],
+ @"Trailers in the NSError object and call object differ.");
+ NSString *challengeHeader = call.oauth2ChallengeHeader;
+ XCTAssertGreaterThan(challengeHeader.length, 0, @"No challenge in response headers %@",
+ call.responseHeaders);
+ [expectation fulfill];
+ }];
[call startWithWriteable:responsesWriteable];
@@ -229,38 +238,43 @@
}
- (void)testResponseMetadataKVO {
- __weak XCTestExpectation *response = [self expectationWithDescription:@"Empty response received."];
+ __weak XCTestExpectation *response =
+ [self expectationWithDescription:@"Empty response received."];
__weak XCTestExpectation *completion = [self expectationWithDescription:@"Empty RPC completed."];
__weak XCTestExpectation *metadata = [self expectationWithDescription:@"Metadata changed."];
-
+
GRPCCall *call = [[GRPCCall alloc] initWithHost:kHostAddress
path:kEmptyCallMethod.HTTPPath
requestsWriter:[GRXWriter writerWithValue:[NSData data]]];
-
- PassthroughObserver *observer = [[PassthroughObserver alloc] initWithCallback:^(NSString *keypath, id object, NSDictionary * change) {
- if ([keypath isEqual: @"responseHeaders"]) {
- [metadata fulfill];
- }
- }];
-
+
+ PassthroughObserver *observer = [[PassthroughObserver alloc]
+ initWithCallback:^(NSString *keypath, id object, NSDictionary *change) {
+ if ([keypath isEqual:@"responseHeaders"]) {
+ [metadata fulfill];
+ }
+ }];
+
[call addObserver:observer forKeyPath:@"responseHeaders" options:0 context:NULL];
-
- id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
- XCTAssertNotNil(value, @"nil value received as response.");
- XCTAssertEqual([value length], 0, @"Non-empty response received: %@", value);
- [response fulfill];
- } completionHandler:^(NSError *errorOrNil) {
- XCTAssertNil(errorOrNil, @"Finished with unexpected error: %@", errorOrNil);
- [completion fulfill];
- }];
-
+
+ id<GRXWriteable> responsesWriteable =
+ [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
+ XCTAssertNotNil(value, @"nil value received as response.");
+ XCTAssertEqual([value length], 0, @"Non-empty response received: %@", value);
+ [response fulfill];
+ }
+ completionHandler:^(NSError *errorOrNil) {
+ XCTAssertNil(errorOrNil, @"Finished with unexpected error: %@", errorOrNil);
+ [completion fulfill];
+ }];
+
[call startWithWriteable:responsesWriteable];
-
+
[self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
}
- (void)testUserAgentPrefix {
- __weak XCTestExpectation *response = [self expectationWithDescription:@"Empty response received."];
+ __weak XCTestExpectation *response =
+ [self expectationWithDescription:@"Empty response received."];
__weak XCTestExpectation *completion = [self expectationWithDescription:@"Empty RPC completed."];
GRPCCall *call = [[GRPCCall alloc] initWithHost:kHostAddress
@@ -270,46 +284,45 @@
// user-agent value, which we confirm.
call.requestHeaders[@"x-grpc-test-echo-useragent"] = @"";
- id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
- XCTAssertNotNil(value, @"nil value received as response.");
- XCTAssertEqual([value length], 0, @"Non-empty response received: %@", value);
+ id<GRXWriteable> responsesWriteable =
+ [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
+ XCTAssertNotNil(value, @"nil value received as response.");
+ XCTAssertEqual([value length], 0, @"Non-empty response received: %@", value);
- NSString *userAgent = call.responseHeaders[@"x-grpc-test-echo-useragent"];
- NSError *error = nil;
+ NSString *userAgent = call.responseHeaders[@"x-grpc-test-echo-useragent"];
+ NSError *error = nil;
- // Test the regex is correct
- NSString *expectedUserAgent = @"Foo grpc-objc/";
- expectedUserAgent =
- [expectedUserAgent stringByAppendingString:GRPC_OBJC_VERSION_STRING];
- expectedUserAgent =
- [expectedUserAgent stringByAppendingString:@" grpc-c/"];
- expectedUserAgent =
- [expectedUserAgent stringByAppendingString:GRPC_C_VERSION_STRING];
- expectedUserAgent =
- [expectedUserAgent stringByAppendingString:@" (ios; chttp2; "];
- expectedUserAgent =
- [expectedUserAgent stringByAppendingString:[NSString stringWithUTF8String:grpc_g_stands_for()]];
- expectedUserAgent = [expectedUserAgent stringByAppendingString:@")"];
- XCTAssertEqualObjects(userAgent, expectedUserAgent);
+ // Test the regex is correct
+ NSString *expectedUserAgent = @"Foo grpc-objc/";
+ expectedUserAgent = [expectedUserAgent stringByAppendingString:GRPC_OBJC_VERSION_STRING];
+ expectedUserAgent = [expectedUserAgent stringByAppendingString:@" grpc-c/"];
+ expectedUserAgent = [expectedUserAgent stringByAppendingString:GRPC_C_VERSION_STRING];
+ expectedUserAgent = [expectedUserAgent stringByAppendingString:@" (ios; chttp2; "];
+ expectedUserAgent = [expectedUserAgent
+ stringByAppendingString:[NSString stringWithUTF8String:grpc_g_stands_for()]];
+ expectedUserAgent = [expectedUserAgent stringByAppendingString:@")"];
+ XCTAssertEqualObjects(userAgent, expectedUserAgent);
- // Change in format of user-agent field in a direction that does not match the regex will likely
- // cause problem for certain gRPC users. For details, refer to internal doc https://goo.gl/c2diBc
- NSRegularExpression *regex =
- [NSRegularExpression regularExpressionWithPattern:@" grpc-[a-zA-Z0-9]+(-[a-zA-Z0-9]+)?/[^ ,]+( \\([^)]*\\))?"
- options:0
- error:&error];
- NSString *customUserAgent =
- [regex stringByReplacingMatchesInString:userAgent
- options:0
- range:NSMakeRange(0, [userAgent length])
- withTemplate:@""];
- XCTAssertEqualObjects(customUserAgent, @"Foo");
+ // Change in format of user-agent field in a direction that does not match the regex will
+ // likely cause problem for certain gRPC users. For details, refer to internal doc
+ // https://goo.gl/c2diBc
+ NSRegularExpression *regex = [NSRegularExpression
+ regularExpressionWithPattern:@" grpc-[a-zA-Z0-9]+(-[a-zA-Z0-9]+)?/[^ ,]+( \\([^)]*\\))?"
+ options:0
+ error:&error];
+ NSString *customUserAgent =
+ [regex stringByReplacingMatchesInString:userAgent
+ options:0
+ range:NSMakeRange(0, [userAgent length])
+ withTemplate:@""];
+ XCTAssertEqualObjects(customUserAgent, @"Foo");
- [response fulfill];
- } completionHandler:^(NSError *errorOrNil) {
- XCTAssertNil(errorOrNil, @"Finished with unexpected error: %@", errorOrNil);
- [completion fulfill];
- }];
+ [response fulfill];
+ }
+ completionHandler:^(NSError *errorOrNil) {
+ XCTAssertNil(errorOrNil, @"Finished with unexpected error: %@", errorOrNil);
+ [completion fulfill];
+ }];
[call startWithWriteable:responsesWriteable];
@@ -317,7 +330,8 @@
}
- (void)testTrailers {
- __weak XCTestExpectation *response = [self expectationWithDescription:@"Empty response received."];
+ __weak XCTestExpectation *response =
+ [self expectationWithDescription:@"Empty response received."];
__weak XCTestExpectation *completion = [self expectationWithDescription:@"Empty RPC completed."];
GRPCCall *call = [[GRPCCall alloc] initWithHost:kHostAddress
@@ -325,21 +339,22 @@
requestsWriter:[GRXWriter writerWithValue:[NSData data]]];
// Setting this special key in the header will cause the interop server to echo back the
// trailer data.
- const unsigned char raw_bytes[] = {1,2,3,4};
+ const unsigned char raw_bytes[] = {1, 2, 3, 4};
NSData *trailer_data = [NSData dataWithBytes:raw_bytes length:sizeof(raw_bytes)];
call.requestHeaders[@"x-grpc-test-echo-trailing-bin"] = trailer_data;
- id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
- XCTAssertNotNil(value, @"nil value received as response.");
- XCTAssertEqual([value length], 0, @"Non-empty response received: %@", value);
- [response fulfill];
- } completionHandler:^(NSError *errorOrNil) {
- XCTAssertNil(errorOrNil, @"Finished with unexpected error: %@", errorOrNil);
- XCTAssertEqualObjects((NSData *)call.responseTrailers[@"x-grpc-test-echo-trailing-bin"],
- trailer_data,
- @"Did not receive expected trailer");
- [completion fulfill];
- }];
+ id<GRXWriteable> responsesWriteable =
+ [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
+ XCTAssertNotNil(value, @"nil value received as response.");
+ XCTAssertEqual([value length], 0, @"Non-empty response received: %@", value);
+ [response fulfill];
+ }
+ completionHandler:^(NSError *errorOrNil) {
+ XCTAssertNil(errorOrNil, @"Finished with unexpected error: %@", errorOrNil);
+ XCTAssertEqualObjects((NSData *)call.responseTrailers[@"x-grpc-test-echo-trailing-bin"],
+ trailer_data, @"Did not receive expected trailer");
+ [completion fulfill];
+ }];
[call startWithWriteable:responsesWriteable];
[self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
@@ -349,15 +364,12 @@
- (void)testExceptions {
// Try to set parameters to nil for GRPCCall. This should cause an exception
@try {
- (void)[[GRPCCall alloc] initWithHost:nil
- path:nil
- requestsWriter:nil];
+ (void)[[GRPCCall alloc] initWithHost:nil path:nil requestsWriter:nil];
XCTFail(@"Did not receive an exception when parameters are nil");
- } @catch(NSException *theException) {
+ } @catch (NSException *theException) {
NSLog(@"Received exception as expected: %@", theException.name);
}
-
// Set state to Finished by force
GRXWriter *requestsWriter = [GRXWriter emptyWriter];
[requestsWriter finishWithError:nil];
@@ -366,10 +378,9 @@
path:kUnaryCallMethod.HTTPPath
requestsWriter:requestsWriter];
XCTFail(@"Did not receive an exception when GRXWriter has incorrect state.");
- } @catch(NSException *theException) {
+ } @catch (NSException *theException) {
NSLog(@"Received exception as expected: %@", theException.name);
}
-
}
- (void)testIdempotentProtoRPC {
@@ -385,20 +396,24 @@
GRPCCall *call = [[GRPCCall alloc] initWithHost:kHostAddress
path:kUnaryCallMethod.HTTPPath
requestsWriter:requestsWriter];
- [GRPCCall setCallSafety:GRPCCallSafetyIdempotentRequest host:kHostAddress path:kUnaryCallMethod.HTTPPath];
+ [GRPCCall setCallSafety:GRPCCallSafetyIdempotentRequest
+ host:kHostAddress
+ path:kUnaryCallMethod.HTTPPath];
- id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
- XCTAssertNotNil(value, @"nil value received as response.");
- XCTAssertGreaterThan(value.length, 0, @"Empty response received.");
- RMTSimpleResponse *responseProto = [RMTSimpleResponse parseFromData:value error:NULL];
- // We expect empty strings, not nil:
- XCTAssertNotNil(responseProto.username, @"Response's username is nil.");
- XCTAssertNotNil(responseProto.oauthScope, @"Response's OAuth scope is nil.");
- [response fulfill];
- } completionHandler:^(NSError *errorOrNil) {
- XCTAssertNil(errorOrNil, @"Finished with unexpected error: %@", errorOrNil);
- [completion fulfill];
- }];
+ id<GRXWriteable> responsesWriteable =
+ [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
+ XCTAssertNotNil(value, @"nil value received as response.");
+ XCTAssertGreaterThan(value.length, 0, @"Empty response received.");
+ RMTSimpleResponse *responseProto = [RMTSimpleResponse parseFromData:value error:NULL];
+ // We expect empty strings, not nil:
+ XCTAssertNotNil(responseProto.username, @"Response's username is nil.");
+ XCTAssertNotNil(responseProto.oauthScope, @"Response's OAuth scope is nil.");
+ [response fulfill];
+ }
+ completionHandler:^(NSError *errorOrNil) {
+ XCTAssertNil(errorOrNil, @"Finished with unexpected error: %@", errorOrNil);
+ [completion fulfill];
+ }];
[call startWithWriteable:responsesWriteable];
@@ -410,10 +425,12 @@
RMTSimpleRequest *request = [RMTSimpleRequest message];
request.responseSize = kPayloadSize;
- __weak XCTestExpectation *expectation1 = [self expectationWithDescription:@"AlternateDispatchQueue1"];
+ __weak XCTestExpectation *expectation1 =
+ [self expectationWithDescription:@"AlternateDispatchQueue1"];
// Use default (main) dispatch queue
- NSString *main_queue_label = [NSString stringWithUTF8String:dispatch_queue_get_label(dispatch_get_main_queue())];
+ NSString *main_queue_label =
+ [NSString stringWithUTF8String:dispatch_queue_get_label(dispatch_get_main_queue())];
GRXWriter *requestsWriter1 = [GRXWriter writerWithValue:[request data]];
@@ -421,20 +438,24 @@
path:kUnaryCallMethod.HTTPPath
requestsWriter:requestsWriter1];
- id<GRXWriteable> responsesWriteable1 = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
- NSString *label = [NSString stringWithUTF8String:dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL)];
- XCTAssert([label isEqualToString:main_queue_label]);
+ id<GRXWriteable> responsesWriteable1 =
+ [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
+ NSString *label =
+ [NSString stringWithUTF8String:dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL)];
+ XCTAssert([label isEqualToString:main_queue_label]);
- [expectation1 fulfill];
- } completionHandler:^(NSError *errorOrNil) {
- }];
+ [expectation1 fulfill];
+ }
+ completionHandler:^(NSError *errorOrNil){
+ }];
[call1 startWithWriteable:responsesWriteable1];
[self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
// Use a custom queue
- __weak XCTestExpectation *expectation2 = [self expectationWithDescription:@"AlternateDispatchQueue2"];
+ __weak XCTestExpectation *expectation2 =
+ [self expectationWithDescription:@"AlternateDispatchQueue2"];
NSString *queue_label = @"test.queue1";
dispatch_queue_t queue = dispatch_queue_create([queue_label UTF8String], DISPATCH_QUEUE_SERIAL);
@@ -447,13 +468,16 @@
[call2 setResponseDispatchQueue:queue];
- id<GRXWriteable> responsesWriteable2 = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
- NSString *label = [NSString stringWithUTF8String:dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL)];
- XCTAssert([label isEqualToString:queue_label]);
+ id<GRXWriteable> responsesWriteable2 =
+ [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
+ NSString *label =
+ [NSString stringWithUTF8String:dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL)];
+ XCTAssert([label isEqualToString:queue_label]);
- [expectation2 fulfill];
- } completionHandler:^(NSError *errorOrNil) {
- }];
+ [expectation2 fulfill];
+ }
+ completionHandler:^(NSError *errorOrNil){
+ }];
[call2 startWithWriteable:responsesWriteable2];
@@ -468,13 +492,16 @@
path:kFullDuplexCallMethod.HTTPPath
requestsWriter:pipe];
- id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
- XCTAssert(0, @"Failure: response received; Expect: no response received.");
- } completionHandler:^(NSError *errorOrNil) {
- XCTAssertNotNil(errorOrNil, @"Failure: no error received; Expect: receive deadline exceeded.");
- XCTAssertEqual(errorOrNil.code, GRPCErrorCodeDeadlineExceeded);
- [completion fulfill];
- }];
+ id<GRXWriteable> responsesWriteable =
+ [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
+ XCTAssert(0, @"Failure: response received; Expect: no response received.");
+ }
+ completionHandler:^(NSError *errorOrNil) {
+ XCTAssertNotNil(errorOrNil,
+ @"Failure: no error received; Expect: receive deadline exceeded.");
+ XCTAssertEqual(errorOrNil.code, GRPCErrorCodeDeadlineExceeded);
+ [completion fulfill];
+ }];
call.timeout = 0.001;
[call startWithWriteable:responsesWriteable];
@@ -482,4 +509,42 @@
[self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
}
+- (int)findFreePort {
+ struct sockaddr_in addr;
+ unsigned int addr_len = sizeof(addr);
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ int fd = socket(AF_INET, SOCK_STREAM, 0);
+ XCTAssertEqual(bind(fd, (struct sockaddr *)&addr, sizeof(addr)), 0);
+ XCTAssertEqual(getsockname(fd, (struct sockaddr *)&addr, &addr_len), 0);
+ XCTAssertEqual(addr_len, sizeof(addr));
+ close(fd);
+ return addr.sin_port;
+}
+
+- (void)testErrorCode {
+ int port = [self findFreePort];
+ NSString *const kDummyAddress = [NSString stringWithFormat:@"localhost:%d", port];
+ __weak XCTestExpectation *completion = [self expectationWithDescription:@"Empty RPC completed."];
+
+ GRPCCall *call = [[GRPCCall alloc] initWithHost:kDummyAddress
+ path:kEmptyCallMethod.HTTPPath
+ requestsWriter:[GRXWriter writerWithValue:[NSData data]]];
+
+ id<GRXWriteable> responsesWriteable =
+ [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
+ // Should not reach here
+ XCTAssert(NO);
+ }
+ completionHandler:^(NSError *errorOrNil) {
+ XCTAssertNotNil(errorOrNil, @"Finished with no error");
+ XCTAssertEqual(errorOrNil.code, GRPC_STATUS_UNAVAILABLE);
+ [completion fulfill];
+ }];
+
+ [call startWithWriteable:responsesWriteable];
+
+ [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
+}
+
@end
diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m
index dfa874a..1e1da2d 100644
--- a/src/objective-c/tests/InteropTests.m
+++ b/src/objective-c/tests/InteropTests.m
@@ -22,17 +22,17 @@
#import <Cronet/Cronet.h>
#import <GRPCClient/GRPCCall+ChannelArg.h>
+#import <GRPCClient/GRPCCall+Cronet.h>
#import <GRPCClient/GRPCCall+Tests.h>
#import <GRPCClient/internal_testing/GRPCCall+InternalTests.h>
-#import <GRPCClient/GRPCCall+Cronet.h>
#import <ProtoRPC/ProtoRPC.h>
#import <RemoteTest/Messages.pbobjc.h>
#import <RemoteTest/Test.pbobjc.h>
#import <RemoteTest/Test.pbrpc.h>
#import <RxLibrary/GRXBufferedPipe.h>
#import <RxLibrary/GRXWriter+Immediate.h>
-#import <grpc/support/log.h>
#import <grpc/grpc.h>
+#import <grpc/support/log.h>
#define TEST_TIMEOUT 32
@@ -61,7 +61,7 @@
@implementation RMTStreamingOutputCallResponse (Constructors)
+ (instancetype)messageWithPayloadSize:(NSNumber *)payloadSize {
- RMTStreamingOutputCallResponse * response = [self message];
+ RMTStreamingOutputCallResponse *response = [self message];
response.payload.type = RMTPayloadType_Compressable;
response.payload.body = [NSMutableData dataWithLength:payloadSize.unsignedIntegerValue];
return response;
@@ -113,14 +113,15 @@
GPBEmpty *request = [GPBEmpty message];
- [_service emptyCallWithRequest:request handler:^(GPBEmpty *response, NSError *error) {
- XCTAssertNil(error, @"Finished with unexpected error: %@", error);
+ [_service emptyCallWithRequest:request
+ handler:^(GPBEmpty *response, NSError *error) {
+ XCTAssertNil(error, @"Finished with unexpected error: %@", error);
- id expectedResponse = [GPBEmpty message];
- XCTAssertEqualObjects(response, expectedResponse);
+ id expectedResponse = [GPBEmpty message];
+ XCTAssertEqualObjects(response, expectedResponse);
- [expectation fulfill];
- }];
+ [expectation fulfill];
+ }];
[self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
}
@@ -134,16 +135,17 @@
request.responseSize = 314159;
request.payload.body = [NSMutableData dataWithLength:271828];
- [_service unaryCallWithRequest:request handler:^(RMTSimpleResponse *response, NSError *error) {
- XCTAssertNil(error, @"Finished with unexpected error: %@", error);
+ [_service unaryCallWithRequest:request
+ handler:^(RMTSimpleResponse *response, NSError *error) {
+ XCTAssertNil(error, @"Finished with unexpected error: %@", error);
- RMTSimpleResponse *expectedResponse = [RMTSimpleResponse message];
- expectedResponse.payload.type = RMTPayloadType_Compressable;
- expectedResponse.payload.body = [NSMutableData dataWithLength:314159];
- XCTAssertEqualObjects(response, expectedResponse);
+ RMTSimpleResponse *expectedResponse = [RMTSimpleResponse message];
+ expectedResponse.payload.type = RMTPayloadType_Compressable;
+ expectedResponse.payload.body = [NSMutableData dataWithLength:314159];
+ XCTAssertEqualObjects(response, expectedResponse);
- [expectation fulfill];
- }];
+ [expectation fulfill];
+ }];
[self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
}
@@ -158,29 +160,30 @@
request.payload.body = [NSMutableData dataWithLength:10];
[GRPCCall enableOpBatchLog:YES];
- [_service unaryCallWithRequest:request handler:^(RMTSimpleResponse *response, NSError *error) {
- XCTAssertNil(error, @"Finished with unexpected error: %@", error);
+ [_service unaryCallWithRequest:request
+ handler:^(RMTSimpleResponse *response, NSError *error) {
+ XCTAssertNil(error, @"Finished with unexpected error: %@", error);
- RMTSimpleResponse *expectedResponse = [RMTSimpleResponse message];
- expectedResponse.payload.type = RMTPayloadType_Compressable;
- expectedResponse.payload.body = [NSMutableData dataWithLength:10];
- XCTAssertEqualObjects(response, expectedResponse);
+ RMTSimpleResponse *expectedResponse = [RMTSimpleResponse message];
+ expectedResponse.payload.type = RMTPayloadType_Compressable;
+ expectedResponse.payload.body = [NSMutableData dataWithLength:10];
+ XCTAssertEqualObjects(response, expectedResponse);
- // The test is a success if there is a batch of exactly 3 ops (SEND_INITIAL_METADATA,
- // SEND_MESSAGE, SEND_CLOSE_FROM_CLIENT). Without packet coalescing each batch of ops contains
- // only one op.
- NSArray *opBatches = [GRPCCall obtainAndCleanOpBatchLog];
- const NSInteger kExpectedOpBatchSize = 3;
- for (NSObject *o in opBatches) {
- if ([o isKindOfClass:[NSArray class]]) {
- NSArray *batch = (NSArray *)o;
- if ([batch count] == kExpectedOpBatchSize) {
- [expectation fulfill];
- break;
- }
- }
- }
- }];
+ // The test is a success if there is a batch of exactly 3 ops
+ // (SEND_INITIAL_METADATA, SEND_MESSAGE, SEND_CLOSE_FROM_CLIENT). Without
+ // packet coalescing each batch of ops contains only one op.
+ NSArray *opBatches = [GRPCCall obtainAndCleanOpBatchLog];
+ const NSInteger kExpectedOpBatchSize = 3;
+ for (NSObject *o in opBatches) {
+ if ([o isKindOfClass:[NSArray class]]) {
+ NSArray *batch = (NSArray *)o;
+ if ([batch count] == kExpectedOpBatchSize) {
+ [expectation fulfill];
+ break;
+ }
+ }
+ }
+ }];
[self waitForExpectationsWithTimeout:16 handler:nil];
[GRPCCall enableOpBatchLog:NO];
@@ -191,14 +194,15 @@
__weak XCTestExpectation *expectation = [self expectationWithDescription:@"MaxResponseSize"];
RMTSimpleRequest *request = [RMTSimpleRequest message];
- const int32_t kPayloadSize = 4 * 1024 * 1024 - self.encodingOverhead; // 4MB - encoding overhead
+ const int32_t kPayloadSize = 4 * 1024 * 1024 - self.encodingOverhead; // 4MB - encoding overhead
request.responseSize = kPayloadSize;
- [_service unaryCallWithRequest:request handler:^(RMTSimpleResponse *response, NSError *error) {
- XCTAssertNil(error, @"Finished with unexpected error: %@", error);
- XCTAssertEqual(response.payload.body.length, kPayloadSize);
- [expectation fulfill];
- }];
+ [_service unaryCallWithRequest:request
+ handler:^(RMTSimpleResponse *response, NSError *error) {
+ XCTAssertNil(error, @"Finished with unexpected error: %@", error);
+ XCTAssertEqual(response.payload.body.length, kPayloadSize);
+ [expectation fulfill];
+ }];
[self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
}
@@ -208,18 +212,23 @@
__weak XCTestExpectation *expectation = [self expectationWithDescription:@"ResponseOverMaxSize"];
RMTSimpleRequest *request = [RMTSimpleRequest message];
- const int32_t kPayloadSize = 4 * 1024 * 1024 - self.encodingOverhead + 1; // 1B over max size
+ const int32_t kPayloadSize = 4 * 1024 * 1024 - self.encodingOverhead + 1; // 1B over max size
request.responseSize = kPayloadSize;
- [_service unaryCallWithRequest:request handler:^(RMTSimpleResponse *response, NSError *error) {
- // TODO(jcanizales): Catch the error and rethrow it with an actionable message:
- // - Use +[GRPCCall setResponseSizeLimit:forHost:] to set a higher limit.
- // - If you're developing the server, consider using response streaming, or let clients filter
- // responses by setting a google.protobuf.FieldMask in the request:
- // https://github.com/google/protobuf/blob/master/src/google/protobuf/field_mask.proto
- XCTAssertEqualObjects(error.localizedDescription, @"Received message larger than max (4194305 vs. 4194304)");
- [expectation fulfill];
- }];
+ [_service unaryCallWithRequest:request
+ handler:^(RMTSimpleResponse *response, NSError *error) {
+ // TODO(jcanizales): Catch the error and rethrow it with an actionable
+ // message:
+ // - Use +[GRPCCall setResponseSizeLimit:forHost:] to set a higher limit.
+ // - If you're developing the server, consider using response streaming,
+ // or let clients filter
+ // responses by setting a google.protobuf.FieldMask in the request:
+ // https://github.com/google/protobuf/blob/master/src/google/protobuf/field_mask.proto
+ XCTAssertEqualObjects(
+ error.localizedDescription,
+ @"Received message larger than max (4194305 vs. 4194304)");
+ [expectation fulfill];
+ }];
[self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
}
@@ -230,16 +239,17 @@
[self expectationWithDescription:@"HigherResponseSizeLimit"];
RMTSimpleRequest *request = [RMTSimpleRequest message];
- const size_t kPayloadSize = 5 * 1024 * 1024; // 5MB
+ const size_t kPayloadSize = 5 * 1024 * 1024; // 5MB
request.responseSize = kPayloadSize;
[GRPCCall setResponseSizeLimit:6 * 1024 * 1024 forHost:self.class.host];
- [_service unaryCallWithRequest:request handler:^(RMTSimpleResponse *response, NSError *error) {
- XCTAssertNil(error, @"Finished with unexpected error: %@", error);
- XCTAssertEqual(response.payload.body.length, kPayloadSize);
- [expectation fulfill];
- }];
+ [_service unaryCallWithRequest:request
+ handler:^(RMTSimpleResponse *response, NSError *error) {
+ XCTAssertNil(error, @"Finished with unexpected error: %@", error);
+ XCTAssertEqual(response.payload.body.length, kPayloadSize);
+ [expectation fulfill];
+ }];
[self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
}
@@ -260,19 +270,21 @@
RMTStreamingInputCallRequest *request4 = [RMTStreamingInputCallRequest message];
request4.payload.body = [NSMutableData dataWithLength:45904];
- GRXWriter *writer = [GRXWriter writerWithContainer:@[request1, request2, request3, request4]];
+ GRXWriter *writer = [GRXWriter writerWithContainer:@[ request1, request2, request3, request4 ]];
[_service streamingInputCallWithRequestsWriter:writer
handler:^(RMTStreamingInputCallResponse *response,
NSError *error) {
- XCTAssertNil(error, @"Finished with unexpected error: %@", error);
+ XCTAssertNil(
+ error, @"Finished with unexpected error: %@", error);
- RMTStreamingInputCallResponse *expectedResponse = [RMTStreamingInputCallResponse message];
- expectedResponse.aggregatedPayloadSize = 74922;
- XCTAssertEqualObjects(response, expectedResponse);
+ RMTStreamingInputCallResponse *expectedResponse =
+ [RMTStreamingInputCallResponse message];
+ expectedResponse.aggregatedPayloadSize = 74922;
+ XCTAssertEqualObjects(response, expectedResponse);
- [expectation fulfill];
- }];
+ [expectation fulfill];
+ }];
[self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
}
@@ -281,7 +293,7 @@
XCTAssertNotNil(self.class.host);
__weak XCTestExpectation *expectation = [self expectationWithDescription:@"ServerStreaming"];
- NSArray *expectedSizes = @[@31415, @9, @2653, @58979];
+ NSArray *expectedSizes = @[ @31415, @9, @2653, @58979 ];
RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message];
for (NSNumber *size in expectedSizes) {
@@ -291,25 +303,27 @@
}
__block int index = 0;
- [_service streamingOutputCallWithRequest:request
- eventHandler:^(BOOL done,
- RMTStreamingOutputCallResponse *response,
- NSError *error){
- XCTAssertNil(error, @"Finished with unexpected error: %@", error);
- XCTAssertTrue(done || response, @"Event handler called without an event.");
+ [_service
+ streamingOutputCallWithRequest:request
+ eventHandler:^(BOOL done, RMTStreamingOutputCallResponse *response,
+ NSError *error) {
+ XCTAssertNil(error, @"Finished with unexpected error: %@", error);
+ XCTAssertTrue(done || response,
+ @"Event handler called without an event.");
- if (response) {
- XCTAssertLessThan(index, 4, @"More than 4 responses received.");
- id expected = [RMTStreamingOutputCallResponse messageWithPayloadSize:expectedSizes[index]];
- XCTAssertEqualObjects(response, expected);
- index += 1;
- }
+ if (response) {
+ XCTAssertLessThan(index, 4, @"More than 4 responses received.");
+ id expected = [RMTStreamingOutputCallResponse
+ messageWithPayloadSize:expectedSizes[index]];
+ XCTAssertEqualObjects(response, expected);
+ index += 1;
+ }
- if (done) {
- XCTAssertEqual(index, 4, @"Received %i responses instead of 4.", index);
- [expectation fulfill];
- }
- }];
+ if (done) {
+ XCTAssertEqual(index, 4, @"Received %i responses instead of 4.", index);
+ [expectation fulfill];
+ }
+ }];
[self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
}
@@ -318,8 +332,8 @@
XCTAssertNotNil(self.class.host);
__weak XCTestExpectation *expectation = [self expectationWithDescription:@"PingPong"];
- NSArray *requests = @[@27182, @8, @1828, @45904];
- NSArray *responses = @[@31415, @9, @2653, @58979];
+ NSArray *requests = @[ @27182, @8, @1828, @45904 ];
+ NSArray *responses = @[ @31415, @9, @2653, @58979 ];
GRXBufferedPipe *requestsBuffer = [[GRXBufferedPipe alloc] init];
@@ -330,31 +344,34 @@
[requestsBuffer writeValue:request];
[_service fullDuplexCallWithRequestsWriter:requestsBuffer
- eventHandler:^(BOOL done,
- RMTStreamingOutputCallResponse *response,
+ eventHandler:^(BOOL done, RMTStreamingOutputCallResponse *response,
NSError *error) {
- XCTAssertNil(error, @"Finished with unexpected error: %@", error);
- XCTAssertTrue(done || response, @"Event handler called without an event.");
+ XCTAssertNil(error, @"Finished with unexpected error: %@", error);
+ XCTAssertTrue(done || response,
+ @"Event handler called without an event.");
- if (response) {
- XCTAssertLessThan(index, 4, @"More than 4 responses received.");
- id expected = [RMTStreamingOutputCallResponse messageWithPayloadSize:responses[index]];
- XCTAssertEqualObjects(response, expected);
- index += 1;
- if (index < 4) {
- id request = [RMTStreamingOutputCallRequest messageWithPayloadSize:requests[index]
- requestedResponseSize:responses[index]];
- [requestsBuffer writeValue:request];
- } else {
- [requestsBuffer writesFinishedWithError:nil];
- }
- }
+ if (response) {
+ XCTAssertLessThan(index, 4, @"More than 4 responses received.");
+ id expected = [RMTStreamingOutputCallResponse
+ messageWithPayloadSize:responses[index]];
+ XCTAssertEqualObjects(response, expected);
+ index += 1;
+ if (index < 4) {
+ id request = [RMTStreamingOutputCallRequest
+ messageWithPayloadSize:requests[index]
+ requestedResponseSize:responses[index]];
+ [requestsBuffer writeValue:request];
+ } else {
+ [requestsBuffer writesFinishedWithError:nil];
+ }
+ }
- if (done) {
- XCTAssertEqual(index, 4, @"Received %i responses instead of 4.", index);
- [expectation fulfill];
- }
- }];
+ if (done) {
+ XCTAssertEqual(index, 4, @"Received %i responses instead of 4.",
+ index);
+ [expectation fulfill];
+ }
+ }];
[self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
}
@@ -362,13 +379,12 @@
XCTAssertNotNil(self.class.host);
__weak XCTestExpectation *expectation = [self expectationWithDescription:@"EmptyStream"];
[_service fullDuplexCallWithRequestsWriter:[GRXWriter emptyWriter]
- eventHandler:^(BOOL done,
- RMTStreamingOutputCallResponse *response,
+ eventHandler:^(BOOL done, RMTStreamingOutputCallResponse *response,
NSError *error) {
- XCTAssertNil(error, @"Finished with unexpected error: %@", error);
- XCTAssert(done, @"Unexpected response: %@", response);
- [expectation fulfill];
- }];
+ XCTAssertNil(error, @"Finished with unexpected error: %@", error);
+ XCTAssert(done, @"Unexpected response: %@", response);
+ [expectation fulfill];
+ }];
[self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
}
@@ -379,13 +395,13 @@
// A buffered pipe to which we never write any value acts as a writer that just hangs.
GRXBufferedPipe *requestsBuffer = [[GRXBufferedPipe alloc] init];
- GRPCProtoCall *call =
- [_service RPCToStreamingInputCallWithRequestsWriter:requestsBuffer
- handler:^(RMTStreamingInputCallResponse *response,
- NSError *error) {
- XCTAssertEqual(error.code, GRPC_STATUS_CANCELLED);
- [expectation fulfill];
- }];
+ GRPCProtoCall *call = [_service
+ RPCToStreamingInputCallWithRequestsWriter:requestsBuffer
+ handler:^(RMTStreamingInputCallResponse *response,
+ NSError *error) {
+ XCTAssertEqual(error.code, GRPC_STATUS_CANCELLED);
+ [expectation fulfill];
+ }];
XCTAssertEqual(call.state, GRXWriterStateNotStarted);
[call start];
@@ -399,35 +415,36 @@
- (void)testCancelAfterFirstResponseRPC {
XCTAssertNotNil(self.class.host);
- __weak XCTestExpectation *expectation = [self expectationWithDescription:@"CancelAfterFirstResponse"];
+ __weak XCTestExpectation *expectation =
+ [self expectationWithDescription:@"CancelAfterFirstResponse"];
// A buffered pipe to which we write a single value but never close
GRXBufferedPipe *requestsBuffer = [[GRXBufferedPipe alloc] init];
__block BOOL receivedResponse = NO;
- id request = [RMTStreamingOutputCallRequest messageWithPayloadSize:@21782
- requestedResponseSize:@31415];
+ id request =
+ [RMTStreamingOutputCallRequest messageWithPayloadSize:@21782 requestedResponseSize:@31415];
[requestsBuffer writeValue:request];
- __block GRPCProtoCall *call =
- [_service RPCToFullDuplexCallWithRequestsWriter:requestsBuffer
- eventHandler:^(BOOL done,
- RMTStreamingOutputCallResponse *response,
- NSError *error) {
- if (receivedResponse) {
- XCTAssert(done, @"Unexpected extra response %@", response);
- XCTAssertEqual(error.code, GRPC_STATUS_CANCELLED);
- [expectation fulfill];
- } else {
- XCTAssertNil(error, @"Finished with unexpected error: %@", error);
- XCTAssertFalse(done, @"Finished without response");
- XCTAssertNotNil(response);
- receivedResponse = YES;
- [call cancel];
- }
- }];
+ __block GRPCProtoCall *call = [_service
+ RPCToFullDuplexCallWithRequestsWriter:requestsBuffer
+ eventHandler:^(BOOL done, RMTStreamingOutputCallResponse *response,
+ NSError *error) {
+ if (receivedResponse) {
+ XCTAssert(done, @"Unexpected extra response %@", response);
+ XCTAssertEqual(error.code, GRPC_STATUS_CANCELLED);
+ [expectation fulfill];
+ } else {
+ XCTAssertNil(error, @"Finished with unexpected error: %@",
+ error);
+ XCTAssertFalse(done, @"Finished without response");
+ XCTAssertNotNil(response);
+ receivedResponse = YES;
+ [call cancel];
+ }
+ }];
[call start];
[self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
}
@@ -439,19 +456,25 @@
GPBEmpty *request = [GPBEmpty message];
- [_service emptyCallWithRequest:request handler:^(GPBEmpty *response, NSError *error) {
- XCTAssertNil(error, @"First RPC finished with unexpected error: %@", error);
+ [_service
+ emptyCallWithRequest:request
+ handler:^(GPBEmpty *response, NSError *error) {
+ XCTAssertNil(error, @"First RPC finished with unexpected error: %@", error);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
- [GRPCCall closeOpenConnections];
+ [GRPCCall closeOpenConnections];
#pragma clang diagnostic pop
- [_service emptyCallWithRequest:request handler:^(GPBEmpty *response, NSError *error) {
- XCTAssertNil(error, @"Second RPC finished with unexpected error: %@", error);
- [expectation fulfill];
- }];
- }];
+ [_service
+ emptyCallWithRequest:request
+ handler:^(GPBEmpty *response, NSError *error) {
+ XCTAssertNil(
+ error, @"Second RPC finished with unexpected error: %@",
+ error);
+ [expectation fulfill];
+ }];
+ }];
[self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
}
@@ -472,18 +495,62 @@
request.expectCompressed.value = YES;
[GRPCCall setDefaultCompressMethod:GRPCCompressGzip forhost:self.class.host];
- [_service unaryCallWithRequest:request handler:^(RMTSimpleResponse *response, NSError *error) {
- XCTAssertNil(error, @"Finished with unexpected error: %@", error);
+ [_service unaryCallWithRequest:request
+ handler:^(RMTSimpleResponse *response, NSError *error) {
+ XCTAssertNil(error, @"Finished with unexpected error: %@", error);
- RMTSimpleResponse *expectedResponse = [RMTSimpleResponse message];
- expectedResponse.payload.type = RMTPayloadType_Compressable;
- expectedResponse.payload.body = [NSMutableData dataWithLength:314159];
- XCTAssertEqualObjects(response, expectedResponse);
+ RMTSimpleResponse *expectedResponse = [RMTSimpleResponse message];
+ expectedResponse.payload.type = RMTPayloadType_Compressable;
+ expectedResponse.payload.body = [NSMutableData dataWithLength:314159];
+ XCTAssertEqualObjects(response, expectedResponse);
- [expectation fulfill];
- }];
+ [expectation fulfill];
+ }];
[self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
}
+#ifndef GRPC_COMPILE_WITH_CRONET
+- (void)testKeepalive {
+ XCTAssertNotNil(self.class.host);
+ __weak XCTestExpectation *expectation = [self expectationWithDescription:@"Keepalive"];
+
+ [GRPCCall setKeepaliveWithInterval:1500 timeout:0 forHost:self.class.host];
+
+ NSArray *requests = @[ @27182, @8 ];
+ NSArray *responses = @[ @31415, @9 ];
+
+ GRXBufferedPipe *requestsBuffer = [[GRXBufferedPipe alloc] init];
+
+ __block int index = 0;
+
+ id request = [RMTStreamingOutputCallRequest messageWithPayloadSize:requests[index]
+ requestedResponseSize:responses[index]];
+ [requestsBuffer writeValue:request];
+
+ [_service
+ fullDuplexCallWithRequestsWriter:requestsBuffer
+ eventHandler:^(BOOL done, RMTStreamingOutputCallResponse *response,
+ NSError *error) {
+ if (index == 0) {
+ XCTAssertNil(error, @"Finished with unexpected error: %@", error);
+ XCTAssertTrue(response, @"Event handler called without an event.");
+ XCTAssertFalse(done);
+ index++;
+ } else {
+ // Keepalive should kick after 1s elapsed and fails the call.
+ XCTAssertNotNil(error);
+ XCTAssertEqual(error.code, GRPC_STATUS_INTERNAL);
+ XCTAssertEqualObjects(
+ error.localizedDescription, @"keepalive watchdog timeout",
+ @"Unexpected failure that is not keepalive watchdog timeout.");
+ XCTAssertTrue(done);
+ [expectation fulfill];
+ }
+ }];
+
+ [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
+}
+#endif
+
@end
diff --git a/src/objective-c/tests/InteropTestsLocalCleartext.m b/src/objective-c/tests/InteropTestsLocalCleartext.m
index aba9868..d49e875 100644
--- a/src/objective-c/tests/InteropTestsLocalCleartext.m
+++ b/src/objective-c/tests/InteropTestsLocalCleartext.m
@@ -25,7 +25,7 @@
// in turn derived from environment variable of the same name.
#define NSStringize_helper(x) #x
#define NSStringize(x) @NSStringize_helper(x)
-static NSString * const kLocalCleartextHost = NSStringize(HOST_PORT_LOCAL);
+static NSString *const kLocalCleartextHost = NSStringize(HOST_PORT_LOCAL);
// The Protocol Buffers encoding overhead of local interop server. Acquired
// by experiment. Adjust this when server's proto file changes.
@@ -42,7 +42,7 @@
}
- (int32_t)encodingOverhead {
- return kLocalInteropServerOverhead; // bytes
+ return kLocalInteropServerOverhead; // bytes
}
- (void)setUp {
diff --git a/src/objective-c/tests/InteropTestsLocalSSL.m b/src/objective-c/tests/InteropTestsLocalSSL.m
index 06176cc..a8c4dc7 100644
--- a/src/objective-c/tests/InteropTestsLocalSSL.m
+++ b/src/objective-c/tests/InteropTestsLocalSSL.m
@@ -24,7 +24,7 @@
// in turn derived from environment variable of the same name.
#define NSStringize_helper(x) #x
#define NSStringize(x) @NSStringize_helper(x)
-static NSString * const kLocalSSLHost = NSStringize(HOST_PORT_LOCALSSL);
+static NSString *const kLocalSSLHost = NSStringize(HOST_PORT_LOCALSSL);
// The Protocol Buffers encoding overhead of local interop server. Acquired
// by experiment. Adjust this when server's proto file changes.
@@ -41,7 +41,7 @@
}
- (int32_t)encodingOverhead {
- return kLocalInteropServerOverhead; // bytes
+ return kLocalInteropServerOverhead; // bytes
}
- (void)setUp {
@@ -49,8 +49,8 @@
// Register test server certificates and name.
NSBundle *bundle = [NSBundle bundleForClass:self.class];
- NSString *certsPath = [bundle pathForResource:@"TestCertificates.bundle/test-certificates"
- ofType:@"pem"];
+ NSString *certsPath =
+ [bundle pathForResource:@"TestCertificates.bundle/test-certificates" ofType:@"pem"];
[GRPCCall useTestCertsPath:certsPath testName:@"foo.test.google.fr" forHost:kLocalSSLHost];
}
@@ -60,7 +60,7 @@
@try {
[GRPCCall useTestCertsPath:nil testName:nil forHost:nil];
XCTFail(@"Did not receive an exception when parameters are nil");
- } @catch(NSException *theException) {
+ } @catch (NSException *theException) {
NSLog(@"Received exception as expected: %@", theException.name);
}
}
diff --git a/src/objective-c/tests/InteropTestsRemote.m b/src/objective-c/tests/InteropTestsRemote.m
index f8133e8..e5738aa 100644
--- a/src/objective-c/tests/InteropTestsRemote.m
+++ b/src/objective-c/tests/InteropTestsRemote.m
@@ -25,7 +25,7 @@
// in turn derived from environment variable of the same name.
#define NSStringize_helper(x) #x
#define NSStringize(x) @NSStringize_helper(x)
-static NSString * const kRemoteSSLHost = NSStringize(HOST_PORT_REMOTE);
+static NSString *const kRemoteSSLHost = NSStringize(HOST_PORT_REMOTE);
// The Protocol Buffers encoding overhead of remote interop server. Acquired
// by experiment. Adjust this when server's proto file changes.
@@ -42,7 +42,7 @@
}
- (int32_t)encodingOverhead {
- return kRemoteInteropServerOverhead; // bytes
+ return kRemoteInteropServerOverhead; // bytes
}
@end
diff --git a/src/objective-c/tests/InteropTestsRemoteWithCronet/InteropTestsRemoteWithCronet.m b/src/objective-c/tests/InteropTestsRemoteWithCronet/InteropTestsRemoteWithCronet.m
index d4eb522..25041ae 100644
--- a/src/objective-c/tests/InteropTestsRemoteWithCronet/InteropTestsRemoteWithCronet.m
+++ b/src/objective-c/tests/InteropTestsRemoteWithCronet/InteropTestsRemoteWithCronet.m
@@ -28,8 +28,7 @@
// in turn derived from environment variable of the same name.
#define NSStringize_helper(x) #x
#define NSStringize(x) @NSStringize_helper(x)
-static NSString * const kRemoteSSLHost = NSStringize(HOST_PORT_REMOTE);
-
+static NSString *const kRemoteSSLHost = NSStringize(HOST_PORT_REMOTE);
// The Protocol Buffers encoding overhead of remote interop server. Acquired
// by experiment. Adjust this when server's proto file changes.
@@ -46,7 +45,7 @@
}
- (int32_t)encodingOverhead {
- return kRemoteInteropServerOverhead; // bytes
+ return kRemoteInteropServerOverhead; // bytes
}
@end
diff --git a/src/objective-c/tests/Podfile b/src/objective-c/tests/Podfile
index 6e17d9a..b6e3897 100644
--- a/src/objective-c/tests/Podfile
+++ b/src/objective-c/tests/Podfile
@@ -26,8 +26,8 @@
pod 'gRPC', :path => GRPC_LOCAL_SRC
pod 'gRPC-Core', :path => GRPC_LOCAL_SRC
pod 'gRPC-RxLibrary', :path => GRPC_LOCAL_SRC
- pod 'gRPC-ProtoRPC', :path => GRPC_LOCAL_SRC
- pod 'RemoteTest', :path => "RemoteTestClient"
+ pod 'gRPC-ProtoRPC', :path => GRPC_LOCAL_SRC, :inhibit_warnings => true
+ pod 'RemoteTest', :path => "RemoteTestClient", :inhibit_warnings => true
if target_name == 'InteropTestsRemoteWithCronet'
pod 'gRPC-Core/Cronet-Implementation', :path => GRPC_LOCAL_SRC
@@ -43,8 +43,10 @@
target target_name do
pod 'BoringSSL', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c", :inhibit_warnings => true
pod 'CronetFramework', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c"
+ pod 'gRPC-Core', :path => GRPC_LOCAL_SRC
+ pod 'gRPC-Core/Cronet-Interface', :path => GRPC_LOCAL_SRC
pod 'gRPC-Core/Cronet-Implementation', :path => GRPC_LOCAL_SRC
- pod 'gRPC-Core/Cronet-Tests', :path => GRPC_LOCAL_SRC
+ pod 'gRPC-Core/Tests', :path => GRPC_LOCAL_SRC
end
end
diff --git a/src/objective-c/tests/RxLibraryUnitTests.m b/src/objective-c/tests/RxLibraryUnitTests.m
index aa178f8..ecd914c 100644
--- a/src/objective-c/tests/RxLibraryUnitTests.m
+++ b/src/objective-c/tests/RxLibraryUnitTests.m
@@ -30,10 +30,10 @@
//
// TODO(jcanizales): Move this to a test util library, and add tests for it.
@interface CapturingSingleValueHandler : NSObject
-@property (nonatomic, readonly) void (^block)(id value, NSError *errorOrNil);
-@property (nonatomic, readonly) NSUInteger timesCalled;
-@property (nonatomic, readonly) id value;
-@property (nonatomic, readonly) NSError *errorOrNil;
+@property(nonatomic, readonly) void (^block)(id value, NSError *errorOrNil);
+@property(nonatomic, readonly) NSUInteger timesCalled;
+@property(nonatomic, readonly) id value;
+@property(nonatomic, readonly) NSError *errorOrNil;
+ (instancetype)handler;
@end
@@ -149,10 +149,11 @@
__weak XCTestExpectation *expectation = [self expectationWithDescription:@"Response received"];
// Given:
CapturingSingleValueHandler *handler = [CapturingSingleValueHandler handler];
- id<GRXWriteable> writeable = [GRXWriteable writeableWithSingleHandler:^(id value, NSError *errorOrNil) {
- handler.block(value, errorOrNil);
- [expectation fulfill];
- }];
+ id<GRXWriteable> writeable =
+ [GRXWriteable writeableWithSingleHandler:^(id value, NSError *errorOrNil) {
+ handler.block(value, errorOrNil);
+ [expectation fulfill];
+ }];
id anyValue = @7;
@@ -167,17 +168,17 @@
XCTAssertEqual(handler.timesCalled, 1);
XCTAssertEqualObjects(handler.value, anyValue);
XCTAssertEqualObjects(handler.errorOrNil, nil);
-
}
- (void)testBufferedPipePropagatesError {
__weak XCTestExpectation *expectation = [self expectationWithDescription:@"Response received"];
// Given:
CapturingSingleValueHandler *handler = [CapturingSingleValueHandler handler];
- id<GRXWriteable> writeable = [GRXWriteable writeableWithSingleHandler:^(id value, NSError *errorOrNil) {
- handler.block(value, errorOrNil);
- [expectation fulfill];
- }];
+ id<GRXWriteable> writeable =
+ [GRXWriteable writeableWithSingleHandler:^(id value, NSError *errorOrNil) {
+ handler.block(value, errorOrNil);
+ [expectation fulfill];
+ }];
NSError *anyError = [NSError errorWithDomain:@"domain" code:7 userInfo:nil];
// If:
@@ -196,10 +197,11 @@
__weak XCTestExpectation *expectation = [self expectationWithDescription:@"Response received"];
// Given:
CapturingSingleValueHandler *handler = [CapturingSingleValueHandler handler];
- id<GRXWriteable> writeable = [GRXWriteable writeableWithSingleHandler:^(id value, NSError *errorOrNil) {
- handler.block(value, errorOrNil);
- [expectation fulfill];
- }];
+ id<GRXWriteable> writeable =
+ [GRXWriteable writeableWithSingleHandler:^(id value, NSError *errorOrNil) {
+ handler.block(value, errorOrNil);
+ [expectation fulfill];
+ }];
id anyValue = @7;
// If:
@@ -220,8 +222,9 @@
#define WRITE_ROUNDS (1000)
- (void)testBufferedPipeResumeWhenDealloc {
id anyValue = @7;
- id<GRXWriteable> writeable = [GRXWriteable writeableWithSingleHandler:^(id value, NSError *errorOrNil) {
- }];
+ id<GRXWriteable> writeable =
+ [GRXWriteable writeableWithSingleHandler:^(id value, NSError *errorOrNil){
+ }];
// Release after alloc;
GRXBufferedPipe *pipe = [GRXBufferedPipe pipe];
diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h
index 6f6cd25..e963709 100644
--- a/src/objective-c/tests/version.h
+++ b/src/objective-c/tests/version.h
@@ -22,6 +22,5 @@
// instead. This file can be regenerated from the template by running
// `tools/buildgen/generate_projects.sh`.
-
-#define GRPC_OBJC_VERSION_STRING @"1.11.0-dev"
+#define GRPC_OBJC_VERSION_STRING @"1.13.0-dev"
#define GRPC_C_VERSION_STRING @"6.0.0-dev"
diff --git a/src/php/bin/run_tests.sh b/src/php/bin/run_tests.sh
index c4712ea..b913166 100755
--- a/src/php/bin/run_tests.sh
+++ b/src/php/bin/run_tests.sh
@@ -21,6 +21,6 @@
cd src/php/bin
source ./determine_extension_dir.sh
# in some jenkins macos machine, somehow the PHP build script can't find libgrpc.dylib
-export DYLD_LIBRARY_PATH=$root/libs/$config
+export DYLD_LIBRARY_PATH=$root/libs/$CONFIG
php $extension_dir -d max_execution_time=300 $(which phpunit) -v --debug \
../tests/unit_tests
diff --git a/src/php/composer.json b/src/php/composer.json
index dbf0cc3..03dffb4 100644
--- a/src/php/composer.json
+++ b/src/php/composer.json
@@ -2,7 +2,7 @@
"name": "grpc/grpc-dev",
"description": "gRPC library for PHP - for Developement use only",
"license": "Apache-2.0",
- "version": "1.11.0",
+ "version": "1.13.0",
"require": {
"php": ">=5.5.0",
"google/protobuf": "^v3.3.0"
diff --git a/src/php/ext/grpc/channel.c b/src/php/ext/grpc/channel.c
index 4054723..35adf6b 100644
--- a/src/php/ext/grpc/channel.c
+++ b/src/php/ext/grpc/channel.c
@@ -54,12 +54,12 @@
#endif
static gpr_mu global_persistent_list_mu;
int le_plink;
+extern HashTable grpc_persistent_list;
/* Frees and destroys an instance of wrapped_grpc_channel */
PHP_GRPC_FREE_WRAPPED_FUNC_START(wrapped_grpc_channel)
- bool is_last_wrapper = false;
- // In_persistent_list is used when the user don't close the channel.
- // In this case, le in the list won't be freed.
+ // In_persistent_list is used when the user don't close the channel,
+ // In this case, channels not in the list should be freed.
bool in_persistent_list = true;
if (p->wrapper != NULL) {
gpr_mu_lock(&p->wrapper->mu);
@@ -69,51 +69,32 @@
php_grpc_int key_len = strlen(p->wrapper->key);
// only destroy the channel here if not found in the persistent list
gpr_mu_lock(&global_persistent_list_mu);
- if (!(PHP_GRPC_PERSISTENT_LIST_FIND(&EG(persistent_list), p->wrapper->key,
+ if (!(PHP_GRPC_PERSISTENT_LIST_FIND(&grpc_persistent_list, p->wrapper->key,
key_len, rsrc))) {
in_persistent_list = false;
grpc_channel_destroy(p->wrapper->wrapped);
free(p->wrapper->target);
free(p->wrapper->args_hashstr);
- if(p->wrapper->creds_hashstr != NULL){
+ if (p->wrapper->creds_hashstr != NULL) {
free(p->wrapper->creds_hashstr);
p->wrapper->creds_hashstr = NULL;
}
+ free(p->wrapper->key);
+ p->wrapper->wrapped = NULL;
+ p->wrapper->target = NULL;
+ p->wrapper->args_hashstr = NULL;
+ p->wrapper->key = NULL;
}
gpr_mu_unlock(&global_persistent_list_mu);
}
}
p->wrapper->ref_count -= 1;
- if (p->wrapper->ref_count == 0) {
- is_last_wrapper = true;
- }
gpr_mu_unlock(&p->wrapper->mu);
- if (is_last_wrapper) {
- if (in_persistent_list) {
- // If ref_count==0 and the key still in the list, it means the user
- // don't call channel->close().persistent list should free the
- // allocation in such case, as well as related wrapped channel.
- if (p->wrapper->wrapped != NULL) {
- gpr_mu_lock(&p->wrapper->mu);
- grpc_channel_destroy(p->wrapper->wrapped);
- free(p->wrapper->target);
- free(p->wrapper->args_hashstr);
- if(p->wrapper->creds_hashstr != NULL){
- free(p->wrapper->creds_hashstr);
- p->wrapper->creds_hashstr = NULL;
- }
- p->wrapper->wrapped = NULL;
- php_grpc_delete_persistent_list_entry(p->wrapper->key,
- strlen(p->wrapper->key)
- TSRMLS_CC);
- gpr_mu_unlock(&p->wrapper->mu);
- }
- }
+ if (!in_persistent_list) {
gpr_mu_destroy(&p->wrapper->mu);
- free(p->wrapper->key);
free(p->wrapper);
+ p->wrapper = NULL;
}
- p->wrapper = NULL;
}
PHP_GRPC_FREE_WRAPPED_FUNC_END()
@@ -214,7 +195,7 @@
le->channel = channel->wrapper;
new_rsrc.ptr = le;
gpr_mu_lock(&global_persistent_list_mu);
- PHP_GRPC_PERSISTENT_LIST_UPDATE(&EG(persistent_list), key, key_len,
+ PHP_GRPC_PERSISTENT_LIST_UPDATE(&grpc_persistent_list, key, key_len,
(void *)&new_rsrc);
gpr_mu_unlock(&global_persistent_list_mu);
}
@@ -330,13 +311,12 @@
gpr_mu_init(&channel->wrapper->mu);
smart_str_free(&buf);
-
if (force_new || (creds != NULL && creds->has_call_creds)) {
// If the ChannelCredentials object was composed with a CallCredentials
// object, there is no way we can tell them apart. Do NOT persist
// them. They should be individually destroyed.
create_channel(channel, target, args, creds);
- } else if (!(PHP_GRPC_PERSISTENT_LIST_FIND(&EG(persistent_list), key,
+ } else if (!(PHP_GRPC_PERSISTENT_LIST_FIND(&grpc_persistent_list, key,
key_len, rsrc))) {
create_and_add_channel_to_persistent_list(
channel, target, args, creds, key, key_len TSRMLS_CC);
@@ -352,7 +332,7 @@
channel, target, args, creds, key, key_len TSRMLS_CC);
} else {
efree(args.args);
- if (channel->wrapper->creds_hashstr != NULL){
+ if (channel->wrapper->creds_hashstr != NULL) {
free(channel->wrapper->creds_hashstr);
channel->wrapper->creds_hashstr = NULL;
}
@@ -481,10 +461,10 @@
grpc_channel_destroy(channel->wrapper->wrapped);
free(channel->wrapper->target);
free(channel->wrapper->args_hashstr);
- if(channel->wrapper->creds_hashstr != NULL){
- free(channel->wrapper->creds_hashstr);
- channel->wrapper->creds_hashstr = NULL;
- }
+ free(channel->wrapper->creds_hashstr);
+ channel->wrapper->creds_hashstr = NULL;
+ channel->wrapper->target = NULL;
+ channel->wrapper->args_hashstr = NULL;
channel->wrapper->wrapped = NULL;
channel->wrapper->is_valid = false;
@@ -494,7 +474,7 @@
}
}
channel->wrapper->ref_count -= 1;
- if(channel->wrapper->ref_count == 0){
+ if (channel->wrapper->ref_count == 0) {
// Mark that the wrapper can be freed because mu should be
// destroyed outside the lock.
is_last_wrapper = true;
@@ -519,12 +499,12 @@
TSRMLS_DC) {
php_grpc_zend_resource *rsrc;
gpr_mu_lock(&global_persistent_list_mu);
- if (PHP_GRPC_PERSISTENT_LIST_FIND(&EG(persistent_list), key,
+ if (PHP_GRPC_PERSISTENT_LIST_FIND(&grpc_persistent_list, key,
key_len, rsrc)) {
channel_persistent_le_t *le;
le = (channel_persistent_le_t *)rsrc->ptr;
le->channel = NULL;
- php_grpc_zend_hash_del(&EG(persistent_list), key, key_len+1);
+ php_grpc_zend_hash_del(&grpc_persistent_list, key, key_len+1);
free(le);
}
gpr_mu_unlock(&global_persistent_list_mu);
@@ -534,12 +514,19 @@
static void php_grpc_channel_plink_dtor(php_grpc_zend_resource *rsrc
TSRMLS_DC) {
channel_persistent_le_t *le = (channel_persistent_le_t *)rsrc->ptr;
+ if (le == NULL) {
+ return;
+ }
if (le->channel != NULL) {
gpr_mu_lock(&le->channel->mu);
if (le->channel->wrapped != NULL) {
grpc_channel_destroy(le->channel->wrapped);
- free(le->channel->target);
free(le->channel->args_hashstr);
+ le->channel->wrapped = NULL;
+ le->channel->target = NULL;
+ le->channel->args_hashstr = NULL;
+ free(le->channel->key);
+ le->channel->key = NULL;
}
gpr_mu_unlock(&le->channel->mu);
}
@@ -587,6 +574,8 @@
gpr_mu_init(&global_persistent_list_mu);
le_plink = zend_register_list_destructors_ex(
NULL, php_grpc_channel_plink_dtor, "Persistent Channel", module_number);
+ zend_hash_init_ex(&grpc_persistent_list, 20, NULL,
+ EG(persistent_list).pDestructor, 1, 0);
PHP_GRPC_INIT_HANDLER(wrapped_grpc_channel, channel_ce_handlers);
return SUCCESS;
}
diff --git a/src/php/ext/grpc/php7_wrapper.h b/src/php/ext/grpc/php7_wrapper.h
index 2f4a536..0239e04 100644
--- a/src/php/ext/grpc/php7_wrapper.h
+++ b/src/php/ext/grpc/php7_wrapper.h
@@ -30,6 +30,8 @@
add_property_string(arg, name, context, b)
#define php_grpc_add_property_stringl(res, name, str, len, b) \
add_property_stringl(res, name, str, len, b)
+#define php_grpc_add_property_zval(res, name, val) \
+ add_property_zval(res, name, val)
#define php_grpc_add_next_index_stringl(data, str, len, b) \
add_next_index_stringl(data, str, len, b)
@@ -38,6 +40,12 @@
#define PHP_GRPC_MAKE_STD_ZVAL(pzv) MAKE_STD_ZVAL(pzv)
#define PHP_GRPC_FREE_STD_ZVAL(pzv)
#define PHP_GRPC_DELREF(zv) Z_DELREF_P(zv)
+#define PHP_GRPC_ADD_STRING_TO_ARRAY(val, key, key_len, str, dup) \
+ add_assoc_string_ex(val, key, key_len , str, dup);
+#define PHP_GRPC_ADD_LONG_TO_ARRAY(val, key, key_len, str) \
+ add_assoc_long_ex(val, key, key_len, str);
+#define PHP_GRPC_ADD_BOOL_TO_ARRAY(val, key, key_len, str) \
+ add_assoc_bool_ex(val, key, key_len, str);
#define RETURN_DESTROY_ZVAL(val) \
RETURN_ZVAL(val, false /* Don't execute copy constructor */, \
@@ -88,6 +96,9 @@
0, NULL); \
data = *tmp##key;
+#define PHP_GRPC_HASH_VALPTR_TO_VAL(data) \
+ &data;
+
#define PHP_GRPC_HASH_FOREACH_LONG_KEY_VAL_START(ht, key, key_type, index,\
data) \
zval **tmp##key = NULL; \
@@ -128,6 +139,8 @@
#define PHP_GRPC_PERSISTENT_LIST_UPDATE(plist, key, len, rsrc) \
zend_hash_update(plist, key, len+1, rsrc, sizeof(php_grpc_zend_resource), \
NULL)
+#define PHP_GRPC_PERSISTENT_LIST_SIZE(plist) \
+ plist.nTableSize
#define PHP_GRPC_GET_CLASS_ENTRY(object) zend_get_class_entry(object TSRMLS_CC)
@@ -143,6 +156,11 @@
add_property_string(arg, name, context)
#define php_grpc_add_property_stringl(res, name, str, len, b) \
add_property_stringl(res, name, str, len)
+#define php_grpc_add_property_zval(res, name, val) do { \
+ zval tmp; \
+ tmp = *val; \
+ add_property_zval(res, name, &tmp); \
+ } while(0)
#define php_grpc_add_next_index_stringl(data, str, len, b) \
add_next_index_stringl(data, str, len)
@@ -152,6 +170,12 @@
pzv = (zval *)emalloc(sizeof(zval));
#define PHP_GRPC_FREE_STD_ZVAL(pzv) efree(pzv);
#define PHP_GRPC_DELREF(zv)
+#define PHP_GRPC_ADD_STRING_TO_ARRAY(val, key, key_len, str, dup) \
+ add_assoc_string_ex(val, key, key_len - 1, str);
+#define PHP_GRPC_ADD_LONG_TO_ARRAY(val, key, key_len, str) \
+ add_assoc_long_ex(val, key, key_len - 1, str);
+#define PHP_GRPC_ADD_BOOL_TO_ARRAY(val, key, key_len, str) \
+ add_assoc_bool_ex(val, key, key_len - 1, str);
#define RETURN_DESTROY_ZVAL(val) \
RETVAL_ZVAL(val, false /* Don't execute copy constructor */, \
@@ -193,6 +217,9 @@
if ((zs_##key) == NULL) {key = NULL; key_type = HASH_KEY_IS_LONG;} \
else {key = (zs_##key)->val; key_type = HASH_KEY_IS_STRING;}
+#define PHP_GRPC_HASH_VALPTR_TO_VAL(data) \
+ Z_PTR_P(data);
+
#define PHP_GRPC_HASH_FOREACH_LONG_KEY_VAL_START(ht, key, key_type, index, \
data) \
zend_string *(zs_##key); \
@@ -230,6 +257,8 @@
#define PHP_GRPC_PERSISTENT_LIST_UPDATE(plist, key, len, rsrc) \
zend_hash_str_update_mem(plist, key, len, rsrc, \
sizeof(php_grpc_zend_resource))
+#define PHP_GRPC_PERSISTENT_LIST_SIZE(plist) \
+ zend_array_count(plist)
#define PHP_GRPC_GET_CLASS_ENTRY(object) Z_OBJ_P(object)->ce
diff --git a/src/php/ext/grpc/php_grpc.c b/src/php/ext/grpc/php_grpc.c
index 5971bab..883ee6f 100644
--- a/src/php/ext/grpc/php_grpc.c
+++ b/src/php/ext/grpc/php_grpc.c
@@ -36,7 +36,7 @@
ZEND_DECLARE_MODULE_GLOBALS(grpc)
static PHP_GINIT_FUNCTION(grpc);
-
+HashTable grpc_persistent_list;
/* {{{ grpc_functions[]
*
* Every user visible function must have an entry in grpc_functions[].
@@ -240,6 +240,8 @@
// WARNING: This function IS being called by PHP when the extension
// is unloaded but the logs were somehow suppressed.
if (GRPC_G(initialized)) {
+ zend_hash_clean(&grpc_persistent_list);
+ zend_hash_destroy(&grpc_persistent_list);
grpc_shutdown_timeval(TSRMLS_C);
grpc_php_shutdown_completion_queue(TSRMLS_C);
grpc_shutdown();
@@ -256,7 +258,6 @@
php_info_print_table_row(2, "grpc support", "enabled");
php_info_print_table_row(2, "grpc module version", PHP_GRPC_VERSION);
php_info_print_table_end();
-
/* Remove comments if you have entries in php.ini
DISPLAY_INI_ENTRIES();
*/
diff --git a/src/php/ext/grpc/server.c b/src/php/ext/grpc/server.c
index a65d233..292d512 100644
--- a/src/php/ext/grpc/server.c
+++ b/src/php/ext/grpc/server.c
@@ -89,8 +89,6 @@
if (args_array == NULL) {
server->wrapped = grpc_server_create(NULL, NULL);
} else {
- //TODO(thinkerou): deal it if key of array is long, crash now on php7
- // and update unit test case
php_grpc_read_args_array(args_array, &args TSRMLS_CC);
server->wrapped = grpc_server_create(&args, NULL);
efree(args.args);
@@ -118,8 +116,8 @@
grpc_call_details_init(&details);
grpc_metadata_array_init(&metadata);
error_code =
- grpc_server_request_call(server->wrapped, &call, &details, &metadata,
- completion_queue, completion_queue, NULL);
+ grpc_server_request_call(server->wrapped, &call, &details, &metadata,
+ completion_queue, completion_queue, NULL);
if (error_code != GRPC_CALL_OK) {
zend_throw_exception(spl_ce_LogicException, "request_call failed",
(long)error_code TSRMLS_CC);
@@ -140,25 +138,12 @@
php_grpc_add_property_string(result, "host", host_text, true);
gpr_free(method_text);
gpr_free(host_text);
-#if PHP_MAJOR_VERSION < 7
- add_property_zval(result, "call", grpc_php_wrap_call(call, true TSRMLS_CC));
- add_property_zval(result, "absolute_deadline",
- grpc_php_wrap_timeval(details.deadline TSRMLS_CC));
- add_property_zval(result, "metadata", grpc_parse_metadata_array(&metadata
- TSRMLS_CC));
-#else
- zval zv_call;
- zval zv_timeval;
- zval zv_md;
- //TODO(thinkerou): why use zval* to unit test error?
- zv_call = *grpc_php_wrap_call(call, true);
- zv_timeval = *grpc_php_wrap_timeval(details.deadline);
- zv_md = *grpc_parse_metadata_array(&metadata);
-
- add_property_zval(result, "call", &zv_call);
- add_property_zval(result, "absolute_deadline", &zv_timeval);
- add_property_zval(result, "metadata", &zv_md);
-#endif
+ php_grpc_add_property_zval(result, "call",
+ grpc_php_wrap_call(call, true TSRMLS_CC));
+ php_grpc_add_property_zval(result, "absolute_deadline",
+ grpc_php_wrap_timeval(details.deadline TSRMLS_CC));
+ php_grpc_add_property_zval(result, "metadata",
+ grpc_parse_metadata_array(&metadata TSRMLS_CC));
cleanup:
grpc_call_details_destroy(&details);
@@ -202,9 +187,9 @@
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sO", &addr, &addr_len,
&creds_obj, grpc_ce_server_credentials) ==
FAILURE) {
- zend_throw_exception(
- spl_ce_InvalidArgumentException,
- "add_http2_port expects a string and a ServerCredentials", 1 TSRMLS_CC);
+ zend_throw_exception(spl_ce_InvalidArgumentException,
+ "add_http2_port expects a string and a "
+ "ServerCredentials", 1 TSRMLS_CC);
return;
}
wrapped_grpc_server_credentials *creds =
diff --git a/src/php/ext/grpc/version.h b/src/php/ext/grpc/version.h
index dd2a701..407d634 100644
--- a/src/php/ext/grpc/version.h
+++ b/src/php/ext/grpc/version.h
@@ -20,6 +20,6 @@
#ifndef VERSION_H
#define VERSION_H
-#define PHP_GRPC_VERSION "1.11.0dev"
+#define PHP_GRPC_VERSION "1.13.0dev"
#endif /* VERSION_H */
diff --git a/src/php/lib/Grpc/BaseStub.php b/src/php/lib/Grpc/BaseStub.php
index 5f3a96f..7860233 100644
--- a/src/php/lib/Grpc/BaseStub.php
+++ b/src/php/lib/Grpc/BaseStub.php
@@ -38,12 +38,13 @@
* - 'update_metadata': (optional) a callback function which takes in a
* metadata array, and returns an updated metadata array
* - 'grpc.primary_user_agent': (optional) a user-agent string
- * @param Channel $channel An already created Channel object (optional)
+ * @param Channel|InterceptorChannel $channel An already created Channel or InterceptorChannel object (optional)
*/
- public function __construct($hostname, $opts, Channel $channel = null)
+ public function __construct($hostname, $opts, $channel = null)
{
$ssl_roots = file_get_contents(
- dirname(__FILE__).'/../../../../etc/roots.pem');
+ dirname(__FILE__).'/../../../../etc/roots.pem'
+ );
ChannelCredentials::setDefaultRootsPem($ssl_roots);
$this->hostname = $hostname;
@@ -58,16 +59,20 @@
$this->hostname_override = $opts['grpc.ssl_target_name_override'];
}
if ($channel) {
- if (!is_a($channel, 'Grpc\Channel')) {
- throw new \Exception('The channel argument is not a'.
- 'Channel object');
+ if (!is_a($channel, 'Grpc\Channel') &&
+ !is_a($channel, 'Grpc\InterceptorChannel')) {
+ throw new \Exception('The channel argument is not a Channel object '.
+ 'or an InterceptorChannel object created by '.
+ 'Interceptor::intercept($channel, Interceptor|Interceptor[] $interceptors)');
}
$this->channel = $channel;
return;
}
$package_config = json_decode(
- file_get_contents(dirname(__FILE__).'/../../composer.json'), true);
+ file_get_contents(dirname(__FILE__).'/../../composer.json'),
+ true
+ );
if (!empty($opts['grpc.primary_user_agent'])) {
$opts['grpc.primary_user_agent'] .= ' ';
} else {
@@ -77,8 +82,8 @@
'grpc-php/'.$package_config['version'];
if (!array_key_exists('credentials', $opts)) {
throw new \Exception("The opts['credentials'] key is now ".
- 'required. Please see one of the '.
- 'ChannelCredentials::create methods');
+ 'required. Please see one of the '.
+ 'ChannelCredentials::create methods');
}
$this->channel = new Channel($hostname, $opts);
}
@@ -169,7 +174,8 @@
$last_slash_idx = strrpos($method, '/');
if ($last_slash_idx === false) {
throw new \InvalidArgumentException(
- 'service name must have a slash');
+ 'service name must have a slash'
+ );
}
$service_name = substr($method, 0, $last_slash_idx);
@@ -197,7 +203,8 @@
if (!preg_match('/^[A-Za-z\d_-]+$/', $key)) {
throw new \InvalidArgumentException(
'Metadata keys must be nonempty strings containing only '.
- 'alphanumeric characters, hyphens and underscores');
+ 'alphanumeric characters, hyphens and underscores'
+ );
}
$metadata_copy[strtolower($key)] = $value;
}
@@ -205,9 +212,255 @@
return $metadata_copy;
}
+ /**
+ * Create a function which can be used to create UnaryCall
+ *
+ * @param Channel|InterceptorChannel $channel
+ * @param callable $deserialize A function that deserializes the response
+ *
+ * @return \Closure
+ */
+ private function _GrpcUnaryUnary($channel, $deserialize)
+ {
+ return function ($method,
+ $argument,
+ array $metadata = [],
+ array $options = []) use ($channel, $deserialize) {
+ $call = new UnaryCall(
+ $channel,
+ $method,
+ $deserialize,
+ $options
+ );
+ $jwt_aud_uri = $this->_get_jwt_aud_uri($method);
+ if (is_callable($this->update_metadata)) {
+ $metadata = call_user_func(
+ $this->update_metadata,
+ $metadata,
+ $jwt_aud_uri
+ );
+ }
+ $metadata = $this->_validate_and_normalize_metadata(
+ $metadata
+ );
+ $call->start($argument, $metadata, $options);
+ return $call;
+ };
+ }
+
+ /**
+ * Create a function which can be used to create ServerStreamingCall
+ *
+ * @param Channel|InterceptorChannel $channel
+ * @param callable $deserialize A function that deserializes the response
+ *
+ * @return \Closure
+ */
+ private function _GrpcStreamUnary($channel, $deserialize)
+ {
+ return function ($method,
+ array $metadata = [],
+ array $options = []) use ($channel, $deserialize) {
+ $call = new ClientStreamingCall(
+ $channel,
+ $method,
+ $deserialize,
+ $options
+ );
+ $jwt_aud_uri = $this->_get_jwt_aud_uri($method);
+ if (is_callable($this->update_metadata)) {
+ $metadata = call_user_func(
+ $this->update_metadata,
+ $metadata,
+ $jwt_aud_uri
+ );
+ }
+ $metadata = $this->_validate_and_normalize_metadata(
+ $metadata
+ );
+ $call->start($metadata);
+ return $call;
+ };
+ }
+
+ /**
+ * Create a function which can be used to create ClientStreamingCall
+ *
+ * @param Channel|InterceptorChannel $channel
+ * @param callable $deserialize A function that deserializes the response
+ *
+ * @return \Closure
+ */
+ private function _GrpcUnaryStream($channel, $deserialize)
+ {
+ return function ($method,
+ $argument,
+ array $metadata = [],
+ array $options = []) use ($channel, $deserialize) {
+ $call = new ServerStreamingCall(
+ $channel,
+ $method,
+ $deserialize,
+ $options
+ );
+ $jwt_aud_uri = $this->_get_jwt_aud_uri($method);
+ if (is_callable($this->update_metadata)) {
+ $metadata = call_user_func(
+ $this->update_metadata,
+ $metadata,
+ $jwt_aud_uri
+ );
+ }
+ $metadata = $this->_validate_and_normalize_metadata(
+ $metadata
+ );
+ $call->start($argument, $metadata, $options);
+ return $call;
+ };
+ }
+
+ /**
+ * Create a function which can be used to create BidiStreamingCall
+ *
+ * @param Channel|InterceptorChannel $channel
+ * @param callable $deserialize A function that deserializes the response
+ *
+ * @return \Closure
+ */
+ private function _GrpcStreamStream($channel, $deserialize)
+ {
+ return function ($method,
+ array $metadata = [],
+ array $options = []) use ($channel ,$deserialize) {
+ $call = new BidiStreamingCall(
+ $channel,
+ $method,
+ $deserialize,
+ $options
+ );
+ $jwt_aud_uri = $this->_get_jwt_aud_uri($method);
+ if (is_callable($this->update_metadata)) {
+ $metadata = call_user_func(
+ $this->update_metadata,
+ $metadata,
+ $jwt_aud_uri
+ );
+ }
+ $metadata = $this->_validate_and_normalize_metadata(
+ $metadata
+ );
+ $call->start($metadata);
+
+ return $call;
+ };
+ }
+
+ /**
+ * Create a function which can be used to create UnaryCall
+ *
+ * @param Channel|InterceptorChannel $channel
+ * @param callable $deserialize A function that deserializes the response
+ *
+ * @return \Closure
+ */
+ private function _UnaryUnaryCallFactory($channel, $deserialize)
+ {
+ if (is_a($channel, 'Grpc\InterceptorChannel')) {
+ return function ($method,
+ $argument,
+ array $metadata = [],
+ array $options = []) use ($channel, $deserialize) {
+ return $channel->getInterceptor()->interceptUnaryUnary(
+ $method,
+ $argument,
+ $metadata,
+ $options,
+ $this->_UnaryUnaryCallFactory($channel->getNext(), $deserialize)
+ );
+ };
+ }
+ return $this->_GrpcUnaryUnary($channel, $deserialize);
+ }
+
+ /**
+ * Create a function which can be used to create ServerStreamingCall
+ *
+ * @param Channel|InterceptorChannel $channel
+ * @param callable $deserialize A function that deserializes the response
+ *
+ * @return \Closure
+ */
+ private function _UnaryStreamCallFactory($channel, $deserialize)
+ {
+ if (is_a($channel, 'Grpc\InterceptorChannel')) {
+ return function ($method,
+ $argument,
+ array $metadata = [],
+ array $options = []) use ($channel, $deserialize) {
+ return $channel->getInterceptor()->interceptUnaryStream(
+ $method,
+ $argument,
+ $metadata,
+ $options,
+ $this->_UnaryStreamCallFactory($channel->getNext(), $deserialize)
+ );
+ };
+ }
+ return $this->_GrpcUnaryStream($channel, $deserialize);
+ }
+
+ /**
+ * Create a function which can be used to create ClientStreamingCall
+ *
+ * @param Channel|InterceptorChannel $channel
+ * @param callable $deserialize A function that deserializes the response
+ *
+ * @return \Closure
+ */
+ private function _StreamUnaryCallFactory($channel, $deserialize)
+ {
+ if (is_a($channel, 'Grpc\InterceptorChannel')) {
+ return function ($method,
+ array $metadata = [],
+ array $options = []) use ($channel, $deserialize) {
+ return $channel->getInterceptor()->interceptStreamUnary(
+ $method,
+ $metadata,
+ $options,
+ $this->_StreamUnaryCallFactory($channel->getNext(), $deserialize)
+ );
+ };
+ }
+ return $this->_GrpcStreamUnary($channel, $deserialize);
+ }
+
+ /**
+ * Create a function which can be used to create BidiStreamingCall
+ *
+ * @param Channel|InterceptorChannel $channel
+ * @param callable $deserialize A function that deserializes the response
+ *
+ * @return \Closure
+ */
+ private function _StreamStreamCallFactory($channel, $deserialize)
+ {
+ if (is_a($channel, 'Grpc\InterceptorChannel')) {
+ return function ($method,
+ array $metadata = [],
+ array $options = []) use ($channel, $deserialize) {
+ return $channel->getInterceptor()->interceptStreamStream(
+ $method,
+ $metadata,
+ $options,
+ $this->_StreamStreamCallFactory($channel->getNext(), $deserialize)
+ );
+ };
+ }
+ return $this->_GrpcStreamStream($channel, $deserialize);
+ }
+
/* This class is intended to be subclassed by generated code, so
* all functions begin with "_" to avoid name collisions. */
-
/**
* Call a remote method that takes a single argument and has a
* single output.
@@ -221,26 +474,15 @@
*
* @return UnaryCall The active call object
*/
- protected function _simpleRequest($method,
- $argument,
- $deserialize,
- array $metadata = [],
- array $options = [])
- {
- $call = new UnaryCall($this->channel,
- $method,
- $deserialize,
- $options);
- $jwt_aud_uri = $this->_get_jwt_aud_uri($method);
- if (is_callable($this->update_metadata)) {
- $metadata = call_user_func($this->update_metadata,
- $metadata,
- $jwt_aud_uri);
- }
- $metadata = $this->_validate_and_normalize_metadata(
- $metadata);
- $call->start($argument, $metadata, $options);
-
+ protected function _simpleRequest(
+ $method,
+ $argument,
+ $deserialize,
+ array $metadata = [],
+ array $options = []
+ ) {
+ $call_factory = $this->_UnaryUnaryCallFactory($this->channel, $deserialize);
+ $call = $call_factory($method, $argument, $metadata, $options);
return $call;
}
@@ -256,25 +498,14 @@
*
* @return ClientStreamingCall The active call object
*/
- protected function _clientStreamRequest($method,
- $deserialize,
- array $metadata = [],
- array $options = [])
- {
- $call = new ClientStreamingCall($this->channel,
- $method,
- $deserialize,
- $options);
- $jwt_aud_uri = $this->_get_jwt_aud_uri($method);
- if (is_callable($this->update_metadata)) {
- $metadata = call_user_func($this->update_metadata,
- $metadata,
- $jwt_aud_uri);
- }
- $metadata = $this->_validate_and_normalize_metadata(
- $metadata);
- $call->start($metadata);
-
+ protected function _clientStreamRequest(
+ $method,
+ $deserialize,
+ array $metadata = [],
+ array $options = []
+ ) {
+ $call_factory = $this->_StreamUnaryCallFactory($this->channel, $deserialize);
+ $call = $call_factory($method, $metadata, $options);
return $call;
}
@@ -291,26 +522,15 @@
*
* @return ServerStreamingCall The active call object
*/
- protected function _serverStreamRequest($method,
- $argument,
- $deserialize,
- array $metadata = [],
- array $options = [])
- {
- $call = new ServerStreamingCall($this->channel,
- $method,
- $deserialize,
- $options);
- $jwt_aud_uri = $this->_get_jwt_aud_uri($method);
- if (is_callable($this->update_metadata)) {
- $metadata = call_user_func($this->update_metadata,
- $metadata,
- $jwt_aud_uri);
- }
- $metadata = $this->_validate_and_normalize_metadata(
- $metadata);
- $call->start($argument, $metadata, $options);
-
+ protected function _serverStreamRequest(
+ $method,
+ $argument,
+ $deserialize,
+ array $metadata = [],
+ array $options = []
+ ) {
+ $call_factory = $this->_UnaryStreamCallFactory($this->channel, $deserialize);
+ $call = $call_factory($method, $argument, $metadata, $options);
return $call;
}
@@ -325,25 +545,14 @@
*
* @return BidiStreamingCall The active call object
*/
- protected function _bidiRequest($method,
- $deserialize,
- array $metadata = [],
- array $options = [])
- {
- $call = new BidiStreamingCall($this->channel,
- $method,
- $deserialize,
- $options);
- $jwt_aud_uri = $this->_get_jwt_aud_uri($method);
- if (is_callable($this->update_metadata)) {
- $metadata = call_user_func($this->update_metadata,
- $metadata,
- $jwt_aud_uri);
- }
- $metadata = $this->_validate_and_normalize_metadata(
- $metadata);
- $call->start($metadata);
-
+ protected function _bidiRequest(
+ $method,
+ $deserialize,
+ array $metadata = [],
+ array $options = []
+ ) {
+ $call_factory = $this->_StreamStreamCallFactory($this->channel, $deserialize);
+ $call = $call_factory($method, $metadata, $options);
return $call;
}
}
diff --git a/src/php/lib/Grpc/Interceptor.php b/src/php/lib/Grpc/Interceptor.php
new file mode 100644
index 0000000..9c1b561
--- /dev/null
+++ b/src/php/lib/Grpc/Interceptor.php
@@ -0,0 +1,86 @@
+<?php
+/*
+ *
+ * Copyright 2018 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.
+ *
+ */
+
+namespace Grpc;
+
+/**
+ * Represents an interceptor that intercept RPC invocations before call starts.
+ * This is an EXPERIMENTAL API.
+ */
+class Interceptor
+{
+ public function interceptUnaryUnary(
+ $method,
+ $argument,
+ array $metadata = [],
+ array $options = [],
+ $continuation
+ ) {
+ return $continuation($method, $argument, $metadata, $options);
+ }
+
+ public function interceptStreamUnary(
+ $method,
+ array $metadata = [],
+ array $options = [],
+ $continuation
+ ) {
+ return $continuation($method, $metadata, $options);
+ }
+
+ public function interceptUnaryStream(
+ $method,
+ $argument,
+ array $metadata = [],
+ array $options = [],
+ $continuation
+ ) {
+ return $continuation($method, $argument, $metadata, $options);
+ }
+
+ public function interceptStreamStream(
+ $method,
+ array $metadata = [],
+ array $options = [],
+ $continuation
+ ) {
+ return $continuation($method, $metadata, $options);
+ }
+
+ /**
+ * Intercept the methods with Channel
+ *
+ * @param Channel|InterceptorChannel $channel An already created Channel or InterceptorChannel object (optional)
+ * @param Interceptor|Interceptor[] $interceptors interceptors to be added
+ *
+ * @return InterceptorChannel
+ */
+ public static function intercept($channel, $interceptors)
+ {
+ if (is_array($interceptors)) {
+ for ($i = count($interceptors) - 1; $i >= 0; $i--) {
+ $channel = new InterceptorChannel($channel, $interceptors[$i]);
+ }
+ } else {
+ $channel = new InterceptorChannel($channel, $interceptors);
+ }
+ return $channel;
+ }
+}
+
diff --git a/src/php/lib/Grpc/Internal/InterceptorChannel.php b/src/php/lib/Grpc/Internal/InterceptorChannel.php
new file mode 100644
index 0000000..9ac0574
--- /dev/null
+++ b/src/php/lib/Grpc/Internal/InterceptorChannel.php
@@ -0,0 +1,76 @@
+<?php
+/*
+ *
+ * Copyright 2018 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.
+ *
+ */
+
+namespace Grpc;
+
+/**
+ * This is a PRIVATE API and can change without notice.
+ */
+class InterceptorChannel
+{
+ private $next = null;
+ private $interceptor;
+
+ /**
+ * @param Channel|InterceptorChannel $channel An already created Channel
+ * or InterceptorChannel object (optional)
+ * @param Interceptor $interceptor
+ */
+ public function __construct($channel, $interceptor)
+ {
+ if (!is_a($channel, 'Grpc\Channel') &&
+ !is_a($channel, 'Grpc\InterceptorChannel')) {
+ throw new \Exception('The channel argument is not a Channel object '.
+ 'or an InterceptorChannel object created by '.
+ 'Interceptor::intercept($channel, Interceptor|Interceptor[] $interceptors)');
+ }
+ $this->interceptor = $interceptor;
+ $this->next = $channel;
+ }
+
+ public function getNext()
+ {
+ return $this->next;
+ }
+
+ public function getInterceptor()
+ {
+ return $this->interceptor;
+ }
+
+ public function getTarget()
+ {
+ return $this->getNext()->getTarget();
+ }
+
+ public function watchConnectivityState($new_state, $deadline)
+ {
+ return $this->getNext()->watchConnectivityState($new_state, $deadline);
+ }
+
+ public function getConnectivityState($try_to_connect = false)
+ {
+ return $this->getNext()->getConnectivityState($try_to_connect);
+ }
+
+ public function close()
+ {
+ return $this->getNext()->close();
+ }
+}
diff --git a/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/BenchmarkService.php b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/BenchmarkService.php
new file mode 100644
index 0000000..906f6a2
--- /dev/null
+++ b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/BenchmarkService.php
@@ -0,0 +1,41 @@
+<?php
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: src/proto/grpc/testing/benchmark_service.proto
+
+namespace GPBMetadata\Src\Proto\Grpc\Testing;
+
+class BenchmarkService
+{
+ public static $is_initialized = false;
+
+ public static function initOnce() {
+ $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
+
+ if (static::$is_initialized == true) {
+ return;
+ }
+ \GPBMetadata\Src\Proto\Grpc\Testing\Messages::initOnce();
+ $pool->internalAddGeneratedFile(hex2bin(
+ "0aef030a2e7372632f70726f746f2f677270632f74657374696e672f6265" .
+ "6e63686d61726b5f736572766963652e70726f746f120c677270632e7465" .
+ "7374696e6732a6030a1042656e63686d61726b5365727669636512460a09" .
+ "556e61727943616c6c121b2e677270632e74657374696e672e53696d706c" .
+ "65526571756573741a1c2e677270632e74657374696e672e53696d706c65" .
+ "526573706f6e7365124e0a0d53747265616d696e6743616c6c121b2e6772" .
+ "70632e74657374696e672e53696d706c65526571756573741a1c2e677270" .
+ "632e74657374696e672e53696d706c65526573706f6e7365280130011252" .
+ "0a1353747265616d696e6746726f6d436c69656e74121b2e677270632e74" .
+ "657374696e672e53696d706c65526571756573741a1c2e677270632e7465" .
+ "7374696e672e53696d706c65526573706f6e7365280112520a1353747265" .
+ "616d696e6746726f6d536572766572121b2e677270632e74657374696e67" .
+ "2e53696d706c65526571756573741a1c2e677270632e74657374696e672e" .
+ "53696d706c65526573706f6e7365300112520a1153747265616d696e6742" .
+ "6f746857617973121b2e677270632e74657374696e672e53696d706c6552" .
+ "6571756573741a1c2e677270632e74657374696e672e53696d706c655265" .
+ "73706f6e736528013001620670726f746f33"
+ ));
+
+ static::$is_initialized = true;
+ }
+}
+
diff --git a/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/CompilerTest.php b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/CompilerTest.php
new file mode 100644
index 0000000..2c4fe92
--- /dev/null
+++ b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/CompilerTest.php
@@ -0,0 +1,37 @@
+<?php
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: src/proto/grpc/testing/compiler_test.proto
+
+namespace GPBMetadata\Src\Proto\Grpc\Testing;
+
+class CompilerTest
+{
+ public static $is_initialized = false;
+
+ public static function initOnce() {
+ $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
+
+ if (static::$is_initialized == true) {
+ return;
+ }
+ $pool->internalAddGeneratedFile(hex2bin(
+ "0aa1030a2a7372632f70726f746f2f677270632f74657374696e672f636f" .
+ "6d70696c65725f746573742e70726f746f120c677270632e74657374696e" .
+ "6722090a0752657175657374220a0a08526573706f6e736532fe010a0853" .
+ "6572766963654112390a084d6574686f64413112152e677270632e746573" .
+ "74696e672e526571756573741a162e677270632e74657374696e672e5265" .
+ "73706f6e7365123b0a084d6574686f64413212152e677270632e74657374" .
+ "696e672e526571756573741a162e677270632e74657374696e672e526573" .
+ "706f6e73652801123b0a084d6574686f64413312152e677270632e746573" .
+ "74696e672e526571756573741a162e677270632e74657374696e672e5265" .
+ "73706f6e73653001123d0a084d6574686f64413412152e677270632e7465" .
+ "7374696e672e526571756573741a162e677270632e74657374696e672e52" .
+ "6573706f6e73652801300132450a08536572766963654212390a084d6574" .
+ "686f64423112152e677270632e74657374696e672e526571756573741a16" .
+ "2e677270632e74657374696e672e526573706f6e7365620670726f746f33"
+ ));
+
+ static::$is_initialized = true;
+ }
+}
+
diff --git a/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Control.php b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Control.php
index 9b3a752..2319bcd 100644
--- a/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Control.php
+++ b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Control.php
@@ -17,7 +17,7 @@
\GPBMetadata\Src\Proto\Grpc\Testing\Payloads::initOnce();
\GPBMetadata\Src\Proto\Grpc\Testing\Stats::initOnce();
$pool->internalAddGeneratedFile(hex2bin(
- "0aa21a0a247372632f70726f746f2f677270632f74657374696e672f636f" .
+ "0abc1a0a247372632f70726f746f2f677270632f74657374696e672f636f" .
"6e74726f6c2e70726f746f120c677270632e74657374696e671a22737263" .
"2f70726f746f2f677270632f74657374696e672f73746174732e70726f74" .
"6f22250a0d506f6973736f6e506172616d7312140a0c6f6666657265645f" .
@@ -31,7 +31,7 @@
"6f7665727269646518022001280912110a09637265645f74797065180320" .
"012809224d0a0a4368616e6e656c417267120c0a046e616d651801200128" .
"0912130a097374725f76616c7565180220012809480012130a09696e745f" .
- "76616c7565180320012805480042070a0576616c756522d5040a0c436c69" .
+ "76616c7565180320012805480042070a0576616c756522ef040a0c436c69" .
"656e74436f6e66696712160a0e7365727665725f74617267657473180120" .
"032809122d0a0b636c69656e745f7479706518022001280e32182e677270" .
"632e74657374696e672e436c69656e745479706512350a0f736563757269" .
@@ -51,85 +51,86 @@
"745f617069180f20012809122e0a0c6368616e6e656c5f61726773181020" .
"03280b32182e677270632e74657374696e672e4368616e6e656c41726712" .
"160a0e746872656164735f7065725f6371181120012805121b0a136d6573" .
- "73616765735f7065725f73747265616d18122001280522380a0c436c6965" .
- "6e7453746174757312280a05737461747318012001280b32192e67727063" .
- "2e74657374696e672e436c69656e74537461747322150a044d61726b120d" .
- "0a05726573657418012001280822680a0a436c69656e7441726773122b0a" .
- "05736574757018012001280b321a2e677270632e74657374696e672e436c" .
- "69656e74436f6e666967480012220a046d61726b18022001280b32122e67" .
- "7270632e74657374696e672e4d61726b480042090a076172677479706522" .
- "fd020a0c536572766572436f6e666967122d0a0b7365727665725f747970" .
- "6518012001280e32182e677270632e74657374696e672e53657276657254" .
- "79706512350a0f73656375726974795f706172616d7318022001280b321c" .
- "2e677270632e74657374696e672e5365637572697479506172616d73120c" .
- "0a04706f7274180420012805121c0a146173796e635f7365727665725f74" .
- "68726561647318072001280512120a0a636f72655f6c696d697418082001" .
- "280512330a0e7061796c6f61645f636f6e66696718092001280b321b2e67" .
- "7270632e74657374696e672e5061796c6f6164436f6e66696712110a0963" .
- "6f72655f6c697374180a2003280512180a106f746865725f736572766572" .
- "5f617069180b2001280912160a0e746872656164735f7065725f6371180c" .
- "20012805121c0a137265736f757263655f71756f74615f73697a6518e907" .
- "20012805122f0a0c6368616e6e656c5f6172677318ea072003280b32182e" .
- "677270632e74657374696e672e4368616e6e656c41726722680a0a536572" .
- "76657241726773122b0a05736574757018012001280b321a2e677270632e" .
- "74657374696e672e536572766572436f6e666967480012220a046d61726b" .
- "18022001280b32122e677270632e74657374696e672e4d61726b48004209" .
- "0a076172677479706522550a0c53657276657253746174757312280a0573" .
- "7461747318012001280b32192e677270632e74657374696e672e53657276" .
- "65725374617473120c0a04706f7274180220012805120d0a05636f726573" .
- "180320012805220d0a0b436f726552657175657374221d0a0c436f726552" .
- "6573706f6e7365120d0a05636f72657318012001280522060a04566f6964" .
- "22fd010a085363656e6172696f120c0a046e616d6518012001280912310a" .
- "0d636c69656e745f636f6e66696718022001280b321a2e677270632e7465" .
- "7374696e672e436c69656e74436f6e66696712130a0b6e756d5f636c6965" .
- "6e747318032001280512310a0d7365727665725f636f6e66696718042001" .
- "280b321a2e677270632e74657374696e672e536572766572436f6e666967" .
- "12130a0b6e756d5f7365727665727318052001280512160a0e7761726d75" .
- "705f7365636f6e647318062001280512190a1162656e63686d61726b5f73" .
- "65636f6e647318072001280512200a18737061776e5f6c6f63616c5f776f" .
- "726b65725f636f756e7418082001280522360a095363656e6172696f7312" .
- "290a097363656e6172696f7318012003280b32162e677270632e74657374" .
- "696e672e5363656e6172696f2284040a155363656e6172696f526573756c" .
- "7453756d6d617279120b0a03717073180120012801121b0a137170735f70" .
- "65725f7365727665725f636f7265180220012801121a0a12736572766572" .
- "5f73797374656d5f74696d6518032001280112180a107365727665725f75" .
- "7365725f74696d65180420012801121a0a12636c69656e745f7379737465" .
- "6d5f74696d6518052001280112180a10636c69656e745f757365725f7469" .
- "6d6518062001280112120a0a6c6174656e63795f35301807200128011212" .
- "0a0a6c6174656e63795f393018082001280112120a0a6c6174656e63795f" .
- "393518092001280112120a0a6c6174656e63795f3939180a200128011213" .
- "0a0b6c6174656e63795f393939180b2001280112180a107365727665725f" .
- "6370755f7573616765180c2001280112260a1e7375636365737366756c5f" .
- "72657175657374735f7065725f7365636f6e64180d2001280112220a1a66" .
- "61696c65645f72657175657374735f7065725f7365636f6e64180e200128" .
- "0112200a18636c69656e745f706f6c6c735f7065725f7265717565737418" .
- "0f2001280112200a187365727665725f706f6c6c735f7065725f72657175" .
- "65737418102001280112220a1a7365727665725f717565726965735f7065" .
- "725f6370755f73656318112001280112220a1a636c69656e745f71756572" .
- "6965735f7065725f6370755f7365631812200128012283030a0e5363656e" .
- "6172696f526573756c7412280a087363656e6172696f18012001280b3216" .
- "2e677270632e74657374696e672e5363656e6172696f122e0a096c617465" .
- "6e6369657318022001280b321b2e677270632e74657374696e672e486973" .
- "746f6772616d44617461122f0a0c636c69656e745f737461747318032003" .
- "280b32192e677270632e74657374696e672e436c69656e74537461747312" .
- "2f0a0c7365727665725f737461747318042003280b32192e677270632e74" .
- "657374696e672e536572766572537461747312140a0c7365727665725f63" .
- "6f72657318052003280512340a0773756d6d61727918062001280b32232e" .
- "677270632e74657374696e672e5363656e6172696f526573756c7453756d" .
- "6d61727912160a0e636c69656e745f737563636573731807200328081216" .
- "0a0e7365727665725f7375636365737318082003280812390a0f72657175" .
- "6573745f726573756c747318092003280b32202e677270632e7465737469" .
- "6e672e52657175657374526573756c74436f756e742a410a0a436c69656e" .
- "7454797065120f0a0b53594e435f434c49454e54100012100a0c4153594e" .
- "435f434c49454e54100112100a0c4f544845525f434c49454e5410022a5b" .
- "0a0a53657276657254797065120f0a0b53594e435f534552564552100012" .
- "100a0c4153594e435f534552564552100112180a144153594e435f47454e" .
- "455249435f534552564552100212100a0c4f544845525f53455256455210" .
- "032a720a075270635479706512090a05554e4152591000120d0a09535452" .
- "45414d494e47100112190a1553545245414d494e475f46524f4d5f434c49" .
- "454e54100212190a1553545245414d494e475f46524f4d5f534552564552" .
- "100312170a1353545245414d494e475f424f54485f574159531004620670" .
- "726f746f33"
+ "73616765735f7065725f73747265616d18122001280512180a107573655f" .
+ "636f616c657363655f61706918132001280822380a0c436c69656e745374" .
+ "6174757312280a05737461747318012001280b32192e677270632e746573" .
+ "74696e672e436c69656e74537461747322150a044d61726b120d0a057265" .
+ "73657418012001280822680a0a436c69656e7441726773122b0a05736574" .
+ "757018012001280b321a2e677270632e74657374696e672e436c69656e74" .
+ "436f6e666967480012220a046d61726b18022001280b32122e677270632e" .
+ "74657374696e672e4d61726b480042090a076172677479706522fd020a0c" .
+ "536572766572436f6e666967122d0a0b7365727665725f74797065180120" .
+ "01280e32182e677270632e74657374696e672e5365727665725479706512" .
+ "350a0f73656375726974795f706172616d7318022001280b321c2e677270" .
+ "632e74657374696e672e5365637572697479506172616d73120c0a04706f" .
+ "7274180420012805121c0a146173796e635f7365727665725f7468726561" .
+ "647318072001280512120a0a636f72655f6c696d69741808200128051233" .
+ "0a0e7061796c6f61645f636f6e66696718092001280b321b2e677270632e" .
+ "74657374696e672e5061796c6f6164436f6e66696712110a09636f72655f" .
+ "6c697374180a2003280512180a106f746865725f7365727665725f617069" .
+ "180b2001280912160a0e746872656164735f7065725f6371180c20012805" .
+ "121c0a137265736f757263655f71756f74615f73697a6518e90720012805" .
+ "122f0a0c6368616e6e656c5f6172677318ea072003280b32182e67727063" .
+ "2e74657374696e672e4368616e6e656c41726722680a0a53657276657241" .
+ "726773122b0a05736574757018012001280b321a2e677270632e74657374" .
+ "696e672e536572766572436f6e666967480012220a046d61726b18022001" .
+ "280b32122e677270632e74657374696e672e4d61726b480042090a076172" .
+ "677479706522550a0c53657276657253746174757312280a057374617473" .
+ "18012001280b32192e677270632e74657374696e672e5365727665725374" .
+ "617473120c0a04706f7274180220012805120d0a05636f72657318032001" .
+ "2805220d0a0b436f726552657175657374221d0a0c436f7265526573706f" .
+ "6e7365120d0a05636f72657318012001280522060a04566f696422fd010a" .
+ "085363656e6172696f120c0a046e616d6518012001280912310a0d636c69" .
+ "656e745f636f6e66696718022001280b321a2e677270632e74657374696e" .
+ "672e436c69656e74436f6e66696712130a0b6e756d5f636c69656e747318" .
+ "032001280512310a0d7365727665725f636f6e66696718042001280b321a" .
+ "2e677270632e74657374696e672e536572766572436f6e66696712130a0b" .
+ "6e756d5f7365727665727318052001280512160a0e7761726d75705f7365" .
+ "636f6e647318062001280512190a1162656e63686d61726b5f7365636f6e" .
+ "647318072001280512200a18737061776e5f6c6f63616c5f776f726b6572" .
+ "5f636f756e7418082001280522360a095363656e6172696f7312290a0973" .
+ "63656e6172696f7318012003280b32162e677270632e74657374696e672e" .
+ "5363656e6172696f2284040a155363656e6172696f526573756c7453756d" .
+ "6d617279120b0a03717073180120012801121b0a137170735f7065725f73" .
+ "65727665725f636f7265180220012801121a0a127365727665725f737973" .
+ "74656d5f74696d6518032001280112180a107365727665725f757365725f" .
+ "74696d65180420012801121a0a12636c69656e745f73797374656d5f7469" .
+ "6d6518052001280112180a10636c69656e745f757365725f74696d651806" .
+ "2001280112120a0a6c6174656e63795f353018072001280112120a0a6c61" .
+ "74656e63795f393018082001280112120a0a6c6174656e63795f39351809" .
+ "2001280112120a0a6c6174656e63795f3939180a2001280112130a0b6c61" .
+ "74656e63795f393939180b2001280112180a107365727665725f6370755f" .
+ "7573616765180c2001280112260a1e7375636365737366756c5f72657175" .
+ "657374735f7065725f7365636f6e64180d2001280112220a1a6661696c65" .
+ "645f72657175657374735f7065725f7365636f6e64180e2001280112200a" .
+ "18636c69656e745f706f6c6c735f7065725f72657175657374180f200128" .
+ "0112200a187365727665725f706f6c6c735f7065725f7265717565737418" .
+ "102001280112220a1a7365727665725f717565726965735f7065725f6370" .
+ "755f73656318112001280112220a1a636c69656e745f717565726965735f" .
+ "7065725f6370755f7365631812200128012283030a0e5363656e6172696f" .
+ "526573756c7412280a087363656e6172696f18012001280b32162e677270" .
+ "632e74657374696e672e5363656e6172696f122e0a096c6174656e636965" .
+ "7318022001280b321b2e677270632e74657374696e672e486973746f6772" .
+ "616d44617461122f0a0c636c69656e745f737461747318032003280b3219" .
+ "2e677270632e74657374696e672e436c69656e745374617473122f0a0c73" .
+ "65727665725f737461747318042003280b32192e677270632e7465737469" .
+ "6e672e536572766572537461747312140a0c7365727665725f636f726573" .
+ "18052003280512340a0773756d6d61727918062001280b32232e67727063" .
+ "2e74657374696e672e5363656e6172696f526573756c7453756d6d617279" .
+ "12160a0e636c69656e745f7375636365737318072003280812160a0e7365" .
+ "727665725f7375636365737318082003280812390a0f726571756573745f" .
+ "726573756c747318092003280b32202e677270632e74657374696e672e52" .
+ "657175657374526573756c74436f756e742a410a0a436c69656e74547970" .
+ "65120f0a0b53594e435f434c49454e54100012100a0c4153594e435f434c" .
+ "49454e54100112100a0c4f544845525f434c49454e5410022a5b0a0a5365" .
+ "7276657254797065120f0a0b53594e435f534552564552100012100a0c41" .
+ "53594e435f534552564552100112180a144153594e435f47454e45524943" .
+ "5f534552564552100212100a0c4f544845525f53455256455210032a720a" .
+ "075270635479706512090a05554e4152591000120d0a0953545245414d49" .
+ "4e47100112190a1553545245414d494e475f46524f4d5f434c49454e5410" .
+ "0212190a1553545245414d494e475f46524f4d5f53455256455210031217" .
+ "0a1353545245414d494e475f424f54485f574159531004620670726f746f" .
+ "33"
));
static::$is_initialized = true;
diff --git a/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Echo.php b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Echo.php
new file mode 100644
index 0000000..77c5230
--- /dev/null
+++ b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Echo.php
@@ -0,0 +1,43 @@
+<?php
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: src/proto/grpc/testing/echo.proto
+
+namespace GPBMetadata\Src\Proto\Grpc\Testing;
+
+class Echo
+{
+ public static $is_initialized = false;
+
+ public static function initOnce() {
+ $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
+
+ if (static::$is_initialized == true) {
+ return;
+ }
+ \GPBMetadata\Src\Proto\Grpc\Testing\EchoMessages::initOnce();
+ $pool->internalAddGeneratedFile(hex2bin(
+ "0aa6040a217372632f70726f746f2f677270632f74657374696e672f6563" .
+ "686f2e70726f746f120c677270632e74657374696e6732f6020a0f456368" .
+ "6f5465737453657276696365123d0a044563686f12192e677270632e7465" .
+ "7374696e672e4563686f526571756573741a1a2e677270632e7465737469" .
+ "6e672e4563686f526573706f6e736512480a0d5265717565737453747265" .
+ "616d12192e677270632e74657374696e672e4563686f526571756573741a" .
+ "1a2e677270632e74657374696e672e4563686f526573706f6e7365280112" .
+ "490a0e526573706f6e736553747265616d12192e677270632e7465737469" .
+ "6e672e4563686f526571756573741a1a2e677270632e74657374696e672e" .
+ "4563686f526573706f6e7365300112470a0a4269646953747265616d1219" .
+ "2e677270632e74657374696e672e4563686f526571756573741a1a2e6772" .
+ "70632e74657374696e672e4563686f526573706f6e73652801300112460a" .
+ "0d556e696d706c656d656e74656412192e677270632e74657374696e672e" .
+ "4563686f526571756573741a1a2e677270632e74657374696e672e456368" .
+ "6f526573706f6e736532620a18556e696d706c656d656e7465644563686f" .
+ "5365727669636512460a0d556e696d706c656d656e74656412192e677270" .
+ "632e74657374696e672e4563686f526571756573741a1a2e677270632e74" .
+ "657374696e672e4563686f526573706f6e7365320e0a0c4e6f5270635365" .
+ "7276696365620670726f746f33"
+ ));
+
+ static::$is_initialized = true;
+ }
+}
+
diff --git a/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/EchoMessages.php b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/EchoMessages.php
new file mode 100644
index 0000000..4bac8a2
--- /dev/null
+++ b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/EchoMessages.php
@@ -0,0 +1,54 @@
+<?php
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: src/proto/grpc/testing/echo_messages.proto
+
+namespace GPBMetadata\Src\Proto\Grpc\Testing;
+
+class EchoMessages
+{
+ public static $is_initialized = false;
+
+ public static function initOnce() {
+ $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
+
+ if (static::$is_initialized == true) {
+ return;
+ }
+ $pool->internalAddGeneratedFile(hex2bin(
+ "0a8f070a2a7372632f70726f746f2f677270632f74657374696e672f6563" .
+ "686f5f6d657373616765732e70726f746f120c677270632e74657374696e" .
+ "6722320a094465627567496e666f12150a0d737461636b5f656e74726965" .
+ "73180120032809120e0a0664657461696c18022001280922500a0b457272" .
+ "6f72537461747573120c0a04636f646518012001280512150a0d6572726f" .
+ "725f6d657373616765180220012809121c0a1462696e6172795f6572726f" .
+ "725f64657461696c7318032001280922e2030a0d52657175657374506172" .
+ "616d7312150a0d6563686f5f646561646c696e65180120012808121e0a16" .
+ "636c69656e745f63616e63656c5f61667465725f7573180220012805121e" .
+ "0a167365727665725f63616e63656c5f61667465725f7573180320012805" .
+ "12150a0d6563686f5f6d65746164617461180420012808121a0a12636865" .
+ "636b5f617574685f636f6e74657874180520012808121f0a17726573706f" .
+ "6e73655f6d6573736167655f6c656e67746818062001280512110a096563" .
+ "686f5f7065657218072001280812200a1865787065637465645f636c6965" .
+ "6e745f6964656e74697479180820012809121c0a14736b69705f63616e63" .
+ "656c6c65645f636865636b18092001280812280a2065787065637465645f" .
+ "7472616e73706f72745f73656375726974795f74797065180a2001280912" .
+ "2b0a0a64656275675f696e666f180b2001280b32172e677270632e746573" .
+ "74696e672e4465627567496e666f12120a0a7365727665725f646965180c" .
+ "20012808121c0a1462696e6172795f6572726f725f64657461696c73180d" .
+ "2001280912310a0e65787065637465645f6572726f72180e2001280b3219" .
+ "2e677270632e74657374696e672e4572726f7253746174757312170a0f73" .
+ "65727665725f736c6565705f7573180f20012805224a0a0b4563686f5265" .
+ "7175657374120f0a076d657373616765180120012809122a0a0570617261" .
+ "6d18022001280b321b2e677270632e74657374696e672e52657175657374" .
+ "506172616d7322460a0e526573706f6e7365506172616d7312180a107265" .
+ "71756573745f646561646c696e65180120012803120c0a04686f73741802" .
+ "20012809120c0a0470656572180320012809224c0a0c4563686f52657370" .
+ "6f6e7365120f0a076d657373616765180120012809122b0a05706172616d" .
+ "18022001280b321c2e677270632e74657374696e672e526573706f6e7365" .
+ "506172616d73620670726f746f33"
+ ));
+
+ static::$is_initialized = true;
+ }
+}
+
diff --git a/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/GPBEmpty.php b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/GPBEmpty.php
new file mode 100644
index 0000000..7198f7d
--- /dev/null
+++ b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/GPBEmpty.php
@@ -0,0 +1,26 @@
+<?php
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: src/proto/grpc/testing/empty.proto
+
+namespace GPBMetadata\Src\Proto\Grpc\Testing;
+
+class GPBEmpty
+{
+ public static $is_initialized = false;
+
+ public static function initOnce() {
+ $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
+
+ if (static::$is_initialized == true) {
+ return;
+ }
+ $pool->internalAddGeneratedFile(hex2bin(
+ "0a430a227372632f70726f746f2f677270632f74657374696e672f656d70" .
+ "74792e70726f746f120c677270632e74657374696e6722070a05456d7074" .
+ "79620670726f746f33"
+ ));
+
+ static::$is_initialized = true;
+ }
+}
+
diff --git a/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Metrics.php b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Metrics.php
new file mode 100644
index 0000000..7ac739f
--- /dev/null
+++ b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Metrics.php
@@ -0,0 +1,36 @@
+<?php
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: src/proto/grpc/testing/metrics.proto
+
+namespace GPBMetadata\Src\Proto\Grpc\Testing;
+
+class Metrics
+{
+ public static $is_initialized = false;
+
+ public static function initOnce() {
+ $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
+
+ if (static::$is_initialized == true) {
+ return;
+ }
+ $pool->internalAddGeneratedFile(hex2bin(
+ "0afb020a247372632f70726f746f2f677270632f74657374696e672f6d65" .
+ "74726963732e70726f746f120c677270632e74657374696e67226c0a0d47" .
+ "61756765526573706f6e7365120c0a046e616d6518012001280912140a0a" .
+ "6c6f6e675f76616c7565180220012803480012160a0c646f75626c655f76" .
+ "616c7565180320012801480012160a0c737472696e675f76616c75651804" .
+ "20012809480042070a0576616c7565221c0a0c4761756765526571756573" .
+ "74120c0a046e616d65180120012809220e0a0c456d7074794d6573736167" .
+ "6532a0010a0e4d6574726963735365727669636512490a0c476574416c6c" .
+ "476175676573121a2e677270632e74657374696e672e456d7074794d6573" .
+ "736167651a1b2e677270632e74657374696e672e4761756765526573706f" .
+ "6e7365300112430a084765744761756765121a2e677270632e7465737469" .
+ "6e672e4761756765526571756573741a1b2e677270632e74657374696e67" .
+ "2e4761756765526573706f6e7365620670726f746f33"
+ ));
+
+ static::$is_initialized = true;
+ }
+}
+
diff --git a/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/ReportQpsScenarioService.php b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/ReportQpsScenarioService.php
new file mode 100644
index 0000000..35a1fb4
--- /dev/null
+++ b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/ReportQpsScenarioService.php
@@ -0,0 +1,30 @@
+<?php
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: src/proto/grpc/testing/report_qps_scenario_service.proto
+
+namespace GPBMetadata\Src\Proto\Grpc\Testing;
+
+class ReportQpsScenarioService
+{
+ public static $is_initialized = false;
+
+ public static function initOnce() {
+ $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
+
+ if (static::$is_initialized == true) {
+ return;
+ }
+ \GPBMetadata\Src\Proto\Grpc\Testing\Control::initOnce();
+ $pool->internalAddGeneratedFile(hex2bin(
+ "0ab0010a387372632f70726f746f2f677270632f74657374696e672f7265" .
+ "706f72745f7170735f7363656e6172696f5f736572766963652e70726f74" .
+ "6f120c677270632e74657374696e67325e0a185265706f72745170735363" .
+ "656e6172696f5365727669636512420a0e5265706f72745363656e617269" .
+ "6f121c2e677270632e74657374696e672e5363656e6172696f526573756c" .
+ "741a122e677270632e74657374696e672e566f6964620670726f746f33"
+ ));
+
+ static::$is_initialized = true;
+ }
+}
+
diff --git a/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Test.php b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Test.php
new file mode 100644
index 0000000..54628cf
--- /dev/null
+++ b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Test.php
@@ -0,0 +1,60 @@
+<?php
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: src/proto/grpc/testing/test.proto
+
+namespace GPBMetadata\Src\Proto\Grpc\Testing;
+
+class Test
+{
+ public static $is_initialized = false;
+
+ public static function initOnce() {
+ $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
+
+ if (static::$is_initialized == true) {
+ return;
+ }
+ \GPBMetadata\Src\Proto\Grpc\Testing\GPBEmpty::initOnce();
+ \GPBMetadata\Src\Proto\Grpc\Testing\Messages::initOnce();
+ $pool->internalAddGeneratedFile(hex2bin(
+ "0a91080a217372632f70726f746f2f677270632f74657374696e672f7465" .
+ "73742e70726f746f120c677270632e74657374696e671a257372632f7072" .
+ "6f746f2f677270632f74657374696e672f6d657373616765732e70726f74" .
+ "6f32cb050a0b546573745365727669636512350a09456d70747943616c6c" .
+ "12132e677270632e74657374696e672e456d7074791a132e677270632e74" .
+ "657374696e672e456d70747912460a09556e61727943616c6c121b2e6772" .
+ "70632e74657374696e672e53696d706c65526571756573741a1c2e677270" .
+ "632e74657374696e672e53696d706c65526573706f6e7365124f0a124361" .
+ "63686561626c65556e61727943616c6c121b2e677270632e74657374696e" .
+ "672e53696d706c65526571756573741a1c2e677270632e74657374696e67" .
+ "2e53696d706c65526573706f6e7365126c0a1353747265616d696e674f75" .
+ "7470757443616c6c12282e677270632e74657374696e672e53747265616d" .
+ "696e674f757470757443616c6c526571756573741a292e677270632e7465" .
+ "7374696e672e53747265616d696e674f757470757443616c6c526573706f" .
+ "6e7365300112690a1253747265616d696e67496e70757443616c6c12272e" .
+ "677270632e74657374696e672e53747265616d696e67496e70757443616c" .
+ "6c526571756573741a282e677270632e74657374696e672e53747265616d" .
+ "696e67496e70757443616c6c526573706f6e7365280112690a0e46756c6c" .
+ "4475706c657843616c6c12282e677270632e74657374696e672e53747265" .
+ "616d696e674f757470757443616c6c526571756573741a292e677270632e" .
+ "74657374696e672e53747265616d696e674f757470757443616c6c526573" .
+ "706f6e73652801300112690a0e48616c664475706c657843616c6c12282e" .
+ "677270632e74657374696e672e53747265616d696e674f75747075744361" .
+ "6c6c526571756573741a292e677270632e74657374696e672e5374726561" .
+ "6d696e674f757470757443616c6c526573706f6e736528013001123d0a11" .
+ "556e696d706c656d656e74656443616c6c12132e677270632e7465737469" .
+ "6e672e456d7074791a132e677270632e74657374696e672e456d70747932" .
+ "550a14556e696d706c656d656e74656453657276696365123d0a11556e69" .
+ "6d706c656d656e74656443616c6c12132e677270632e74657374696e672e" .
+ "456d7074791a132e677270632e74657374696e672e456d7074793289010a" .
+ "105265636f6e6e65637453657276696365123b0a055374617274121d2e67" .
+ "7270632e74657374696e672e5265636f6e6e656374506172616d731a132e" .
+ "677270632e74657374696e672e456d70747912380a0453746f7012132e67" .
+ "7270632e74657374696e672e456d7074791a1b2e677270632e7465737469" .
+ "6e672e5265636f6e6e656374496e666f620670726f746f33"
+ ));
+
+ static::$is_initialized = true;
+ }
+}
+
diff --git a/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/WorkerService.php b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/WorkerService.php
new file mode 100644
index 0000000..a8a863d
--- /dev/null
+++ b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/WorkerService.php
@@ -0,0 +1,36 @@
+<?php
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: src/proto/grpc/testing/worker_service.proto
+
+namespace GPBMetadata\Src\Proto\Grpc\Testing;
+
+class WorkerService
+{
+ public static $is_initialized = false;
+
+ public static function initOnce() {
+ $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
+
+ if (static::$is_initialized == true) {
+ return;
+ }
+ \GPBMetadata\Src\Proto\Grpc\Testing\Control::initOnce();
+ $pool->internalAddGeneratedFile(hex2bin(
+ "0add020a2b7372632f70726f746f2f677270632f74657374696e672f776f" .
+ "726b65725f736572766963652e70726f746f120c677270632e7465737469" .
+ "6e673297020a0d576f726b65725365727669636512450a0952756e536572" .
+ "76657212182e677270632e74657374696e672e536572766572417267731a" .
+ "1a2e677270632e74657374696e672e536572766572537461747573280130" .
+ "0112450a0952756e436c69656e7412182e677270632e74657374696e672e" .
+ "436c69656e74417267731a1a2e677270632e74657374696e672e436c6965" .
+ "6e745374617475732801300112420a09436f7265436f756e7412192e6772" .
+ "70632e74657374696e672e436f7265526571756573741a1a2e677270632e" .
+ "74657374696e672e436f7265526573706f6e736512340a0a51756974576f" .
+ "726b657212122e677270632e74657374696e672e566f69641a122e677270" .
+ "632e74657374696e672e566f6964620670726f746f33"
+ ));
+
+ static::$is_initialized = true;
+ }
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ClientConfig.php b/src/php/tests/qps/generated_code/Grpc/Testing/ClientConfig.php
index f7bc215..0dd3072 100644
--- a/src/php/tests/qps/generated_code/Grpc/Testing/ClientConfig.php
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ClientConfig.php
@@ -97,6 +97,12 @@
* Generated from protobuf field <code>int32 messages_per_stream = 18;</code>
*/
private $messages_per_stream = 0;
+ /**
+ * Use coalescing API when possible.
+ *
+ * Generated from protobuf field <code>bool use_coalesce_api = 19;</code>
+ */
+ private $use_coalesce_api = false;
public function __construct() {
\GPBMetadata\Src\Proto\Grpc\Testing\Control::initOnce();
@@ -495,5 +501,31 @@
return $this;
}
+ /**
+ * Use coalescing API when possible.
+ *
+ * Generated from protobuf field <code>bool use_coalesce_api = 19;</code>
+ * @return bool
+ */
+ public function getUseCoalesceApi()
+ {
+ return $this->use_coalesce_api;
+ }
+
+ /**
+ * Use coalescing API when possible.
+ *
+ * Generated from protobuf field <code>bool use_coalesce_api = 19;</code>
+ * @param bool $var
+ * @return $this
+ */
+ public function setUseCoalesceApi($var)
+ {
+ GPBUtil::checkBool($var);
+ $this->use_coalesce_api = $var;
+
+ return $this;
+ }
+
}
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/DebugInfo.php b/src/php/tests/qps/generated_code/Grpc/Testing/DebugInfo.php
new file mode 100644
index 0000000..805b629
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/DebugInfo.php
@@ -0,0 +1,77 @@
+<?php
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: src/proto/grpc/testing/echo_messages.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Message to be echoed back serialized in trailer.
+ *
+ * Generated from protobuf message <code>grpc.testing.DebugInfo</code>
+ */
+class DebugInfo extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * Generated from protobuf field <code>repeated string stack_entries = 1;</code>
+ */
+ private $stack_entries;
+ /**
+ * Generated from protobuf field <code>string detail = 2;</code>
+ */
+ private $detail = '';
+
+ public function __construct() {
+ \GPBMetadata\Src\Proto\Grpc\Testing\EchoMessages::initOnce();
+ parent::__construct();
+ }
+
+ /**
+ * Generated from protobuf field <code>repeated string stack_entries = 1;</code>
+ * @return \Google\Protobuf\Internal\RepeatedField
+ */
+ public function getStackEntries()
+ {
+ return $this->stack_entries;
+ }
+
+ /**
+ * Generated from protobuf field <code>repeated string stack_entries = 1;</code>
+ * @param string[]|\Google\Protobuf\Internal\RepeatedField $var
+ * @return $this
+ */
+ public function setStackEntries($var)
+ {
+ $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING);
+ $this->stack_entries = $arr;
+
+ return $this;
+ }
+
+ /**
+ * Generated from protobuf field <code>string detail = 2;</code>
+ * @return string
+ */
+ public function getDetail()
+ {
+ return $this->detail;
+ }
+
+ /**
+ * Generated from protobuf field <code>string detail = 2;</code>
+ * @param string $var
+ * @return $this
+ */
+ public function setDetail($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->detail = $var;
+
+ return $this;
+ }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/EchoRequest.php b/src/php/tests/qps/generated_code/Grpc/Testing/EchoRequest.php
new file mode 100644
index 0000000..9aadfc5
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/EchoRequest.php
@@ -0,0 +1,75 @@
+<?php
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: src/proto/grpc/testing/echo_messages.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Generated from protobuf message <code>grpc.testing.EchoRequest</code>
+ */
+class EchoRequest extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * Generated from protobuf field <code>string message = 1;</code>
+ */
+ private $message = '';
+ /**
+ * Generated from protobuf field <code>.grpc.testing.RequestParams param = 2;</code>
+ */
+ private $param = null;
+
+ public function __construct() {
+ \GPBMetadata\Src\Proto\Grpc\Testing\EchoMessages::initOnce();
+ parent::__construct();
+ }
+
+ /**
+ * Generated from protobuf field <code>string message = 1;</code>
+ * @return string
+ */
+ public function getMessage()
+ {
+ return $this->message;
+ }
+
+ /**
+ * Generated from protobuf field <code>string message = 1;</code>
+ * @param string $var
+ * @return $this
+ */
+ public function setMessage($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->message = $var;
+
+ return $this;
+ }
+
+ /**
+ * Generated from protobuf field <code>.grpc.testing.RequestParams param = 2;</code>
+ * @return \Grpc\Testing\RequestParams
+ */
+ public function getParam()
+ {
+ return $this->param;
+ }
+
+ /**
+ * Generated from protobuf field <code>.grpc.testing.RequestParams param = 2;</code>
+ * @param \Grpc\Testing\RequestParams $var
+ * @return $this
+ */
+ public function setParam($var)
+ {
+ GPBUtil::checkMessage($var, \Grpc\Testing\RequestParams::class);
+ $this->param = $var;
+
+ return $this;
+ }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/EchoResponse.php b/src/php/tests/qps/generated_code/Grpc/Testing/EchoResponse.php
new file mode 100644
index 0000000..c4a9db3
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/EchoResponse.php
@@ -0,0 +1,75 @@
+<?php
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: src/proto/grpc/testing/echo_messages.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Generated from protobuf message <code>grpc.testing.EchoResponse</code>
+ */
+class EchoResponse extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * Generated from protobuf field <code>string message = 1;</code>
+ */
+ private $message = '';
+ /**
+ * Generated from protobuf field <code>.grpc.testing.ResponseParams param = 2;</code>
+ */
+ private $param = null;
+
+ public function __construct() {
+ \GPBMetadata\Src\Proto\Grpc\Testing\EchoMessages::initOnce();
+ parent::__construct();
+ }
+
+ /**
+ * Generated from protobuf field <code>string message = 1;</code>
+ * @return string
+ */
+ public function getMessage()
+ {
+ return $this->message;
+ }
+
+ /**
+ * Generated from protobuf field <code>string message = 1;</code>
+ * @param string $var
+ * @return $this
+ */
+ public function setMessage($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->message = $var;
+
+ return $this;
+ }
+
+ /**
+ * Generated from protobuf field <code>.grpc.testing.ResponseParams param = 2;</code>
+ * @return \Grpc\Testing\ResponseParams
+ */
+ public function getParam()
+ {
+ return $this->param;
+ }
+
+ /**
+ * Generated from protobuf field <code>.grpc.testing.ResponseParams param = 2;</code>
+ * @param \Grpc\Testing\ResponseParams $var
+ * @return $this
+ */
+ public function setParam($var)
+ {
+ GPBUtil::checkMessage($var, \Grpc\Testing\ResponseParams::class);
+ $this->param = $var;
+
+ return $this;
+ }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/EchoTestServiceClient.php b/src/php/tests/qps/generated_code/Grpc/Testing/EchoTestServiceClient.php
new file mode 100644
index 0000000..b3dcf5b
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/EchoTestServiceClient.php
@@ -0,0 +1,93 @@
+<?php
+// GENERATED CODE -- DO NOT EDIT!
+
+// Original file comments:
+// 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.
+//
+namespace Grpc\Testing;
+
+/**
+ */
+class EchoTestServiceClient extends \Grpc\BaseStub {
+
+ /**
+ * @param string $hostname hostname
+ * @param array $opts channel options
+ * @param \Grpc\Channel $channel (optional) re-use channel object
+ */
+ public function __construct($hostname, $opts, $channel = null) {
+ parent::__construct($hostname, $opts, $channel);
+ }
+
+ /**
+ * @param \Grpc\Testing\EchoRequest $argument input argument
+ * @param array $metadata metadata
+ * @param array $options call options
+ */
+ public function Echo(\Grpc\Testing\EchoRequest $argument,
+ $metadata = [], $options = []) {
+ return $this->_simpleRequest('/grpc.testing.EchoTestService/Echo',
+ $argument,
+ ['\Grpc\Testing\EchoResponse', 'decode'],
+ $metadata, $options);
+ }
+
+ /**
+ * @param array $metadata metadata
+ * @param array $options call options
+ */
+ public function RequestStream($metadata = [], $options = []) {
+ return $this->_clientStreamRequest('/grpc.testing.EchoTestService/RequestStream',
+ ['\Grpc\Testing\EchoResponse','decode'],
+ $metadata, $options);
+ }
+
+ /**
+ * @param \Grpc\Testing\EchoRequest $argument input argument
+ * @param array $metadata metadata
+ * @param array $options call options
+ */
+ public function ResponseStream(\Grpc\Testing\EchoRequest $argument,
+ $metadata = [], $options = []) {
+ return $this->_serverStreamRequest('/grpc.testing.EchoTestService/ResponseStream',
+ $argument,
+ ['\Grpc\Testing\EchoResponse', 'decode'],
+ $metadata, $options);
+ }
+
+ /**
+ * @param array $metadata metadata
+ * @param array $options call options
+ */
+ public function BidiStream($metadata = [], $options = []) {
+ return $this->_bidiRequest('/grpc.testing.EchoTestService/BidiStream',
+ ['\Grpc\Testing\EchoResponse','decode'],
+ $metadata, $options);
+ }
+
+ /**
+ * @param \Grpc\Testing\EchoRequest $argument input argument
+ * @param array $metadata metadata
+ * @param array $options call options
+ */
+ public function Unimplemented(\Grpc\Testing\EchoRequest $argument,
+ $metadata = [], $options = []) {
+ return $this->_simpleRequest('/grpc.testing.EchoTestService/Unimplemented',
+ $argument,
+ ['\Grpc\Testing\EchoResponse', 'decode'],
+ $metadata, $options);
+ }
+
+}
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/EmptyMessage.php b/src/php/tests/qps/generated_code/Grpc/Testing/EmptyMessage.php
new file mode 100644
index 0000000..3da163e
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/EmptyMessage.php
@@ -0,0 +1,23 @@
+<?php
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: src/proto/grpc/testing/metrics.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Generated from protobuf message <code>grpc.testing.EmptyMessage</code>
+ */
+class EmptyMessage extends \Google\Protobuf\Internal\Message
+{
+
+ public function __construct() {
+ \GPBMetadata\Src\Proto\Grpc\Testing\Metrics::initOnce();
+ parent::__construct();
+ }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ErrorStatus.php b/src/php/tests/qps/generated_code/Grpc/Testing/ErrorStatus.php
new file mode 100644
index 0000000..cc37875
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ErrorStatus.php
@@ -0,0 +1,103 @@
+<?php
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: src/proto/grpc/testing/echo_messages.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Error status client expects to see.
+ *
+ * Generated from protobuf message <code>grpc.testing.ErrorStatus</code>
+ */
+class ErrorStatus extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * Generated from protobuf field <code>int32 code = 1;</code>
+ */
+ private $code = 0;
+ /**
+ * Generated from protobuf field <code>string error_message = 2;</code>
+ */
+ private $error_message = '';
+ /**
+ * Generated from protobuf field <code>string binary_error_details = 3;</code>
+ */
+ private $binary_error_details = '';
+
+ public function __construct() {
+ \GPBMetadata\Src\Proto\Grpc\Testing\EchoMessages::initOnce();
+ parent::__construct();
+ }
+
+ /**
+ * Generated from protobuf field <code>int32 code = 1;</code>
+ * @return int
+ */
+ public function getCode()
+ {
+ return $this->code;
+ }
+
+ /**
+ * Generated from protobuf field <code>int32 code = 1;</code>
+ * @param int $var
+ * @return $this
+ */
+ public function setCode($var)
+ {
+ GPBUtil::checkInt32($var);
+ $this->code = $var;
+
+ return $this;
+ }
+
+ /**
+ * Generated from protobuf field <code>string error_message = 2;</code>
+ * @return string
+ */
+ public function getErrorMessage()
+ {
+ return $this->error_message;
+ }
+
+ /**
+ * Generated from protobuf field <code>string error_message = 2;</code>
+ * @param string $var
+ * @return $this
+ */
+ public function setErrorMessage($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->error_message = $var;
+
+ return $this;
+ }
+
+ /**
+ * Generated from protobuf field <code>string binary_error_details = 3;</code>
+ * @return string
+ */
+ public function getBinaryErrorDetails()
+ {
+ return $this->binary_error_details;
+ }
+
+ /**
+ * Generated from protobuf field <code>string binary_error_details = 3;</code>
+ * @param string $var
+ * @return $this
+ */
+ public function setBinaryErrorDetails($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->binary_error_details = $var;
+
+ return $this;
+ }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/GaugeRequest.php b/src/php/tests/qps/generated_code/Grpc/Testing/GaugeRequest.php
new file mode 100644
index 0000000..3c28369
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/GaugeRequest.php
@@ -0,0 +1,51 @@
+<?php
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: src/proto/grpc/testing/metrics.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Request message containing the gauge name
+ *
+ * Generated from protobuf message <code>grpc.testing.GaugeRequest</code>
+ */
+class GaugeRequest extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * Generated from protobuf field <code>string name = 1;</code>
+ */
+ private $name = '';
+
+ public function __construct() {
+ \GPBMetadata\Src\Proto\Grpc\Testing\Metrics::initOnce();
+ parent::__construct();
+ }
+
+ /**
+ * Generated from protobuf field <code>string name = 1;</code>
+ * @return string
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * Generated from protobuf field <code>string name = 1;</code>
+ * @param string $var
+ * @return $this
+ */
+ public function setName($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->name = $var;
+
+ return $this;
+ }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/GaugeResponse.php b/src/php/tests/qps/generated_code/Grpc/Testing/GaugeResponse.php
new file mode 100644
index 0000000..da658ba
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/GaugeResponse.php
@@ -0,0 +1,126 @@
+<?php
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: src/proto/grpc/testing/metrics.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Reponse message containing the gauge name and value
+ *
+ * Generated from protobuf message <code>grpc.testing.GaugeResponse</code>
+ */
+class GaugeResponse extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * Generated from protobuf field <code>string name = 1;</code>
+ */
+ private $name = '';
+ protected $value;
+
+ public function __construct() {
+ \GPBMetadata\Src\Proto\Grpc\Testing\Metrics::initOnce();
+ parent::__construct();
+ }
+
+ /**
+ * Generated from protobuf field <code>string name = 1;</code>
+ * @return string
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * Generated from protobuf field <code>string name = 1;</code>
+ * @param string $var
+ * @return $this
+ */
+ public function setName($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->name = $var;
+
+ return $this;
+ }
+
+ /**
+ * Generated from protobuf field <code>int64 long_value = 2;</code>
+ * @return int|string
+ */
+ public function getLongValue()
+ {
+ return $this->readOneof(2);
+ }
+
+ /**
+ * Generated from protobuf field <code>int64 long_value = 2;</code>
+ * @param int|string $var
+ * @return $this
+ */
+ public function setLongValue($var)
+ {
+ GPBUtil::checkInt64($var);
+ $this->writeOneof(2, $var);
+
+ return $this;
+ }
+
+ /**
+ * Generated from protobuf field <code>double double_value = 3;</code>
+ * @return float
+ */
+ public function getDoubleValue()
+ {
+ return $this->readOneof(3);
+ }
+
+ /**
+ * Generated from protobuf field <code>double double_value = 3;</code>
+ * @param float $var
+ * @return $this
+ */
+ public function setDoubleValue($var)
+ {
+ GPBUtil::checkDouble($var);
+ $this->writeOneof(3, $var);
+
+ return $this;
+ }
+
+ /**
+ * Generated from protobuf field <code>string string_value = 4;</code>
+ * @return string
+ */
+ public function getStringValue()
+ {
+ return $this->readOneof(4);
+ }
+
+ /**
+ * Generated from protobuf field <code>string string_value = 4;</code>
+ * @param string $var
+ * @return $this
+ */
+ public function setStringValue($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->writeOneof(4, $var);
+
+ return $this;
+ }
+
+ /**
+ * @return string
+ */
+ public function getValue()
+ {
+ return $this->whichOneof("value");
+ }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/MetricsServiceClient.php b/src/php/tests/qps/generated_code/Grpc/Testing/MetricsServiceClient.php
new file mode 100644
index 0000000..491ccbc
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/MetricsServiceClient.php
@@ -0,0 +1,69 @@
+<?php
+// GENERATED CODE -- DO NOT EDIT!
+
+// Original file comments:
+// Copyright 2015-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.
+//
+// Contains the definitions for a metrics service and the type of metrics
+// exposed by the service.
+//
+// Currently, 'Gauge' (i.e a metric that represents the measured value of
+// something at an instant of time) is the only metric type supported by the
+// service.
+namespace Grpc\Testing;
+
+/**
+ */
+class MetricsServiceClient extends \Grpc\BaseStub {
+
+ /**
+ * @param string $hostname hostname
+ * @param array $opts channel options
+ * @param \Grpc\Channel $channel (optional) re-use channel object
+ */
+ public function __construct($hostname, $opts, $channel = null) {
+ parent::__construct($hostname, $opts, $channel);
+ }
+
+ /**
+ * Returns the values of all the gauges that are currently being maintained by
+ * the service
+ * @param \Grpc\Testing\EmptyMessage $argument input argument
+ * @param array $metadata metadata
+ * @param array $options call options
+ */
+ public function GetAllGauges(\Grpc\Testing\EmptyMessage $argument,
+ $metadata = [], $options = []) {
+ return $this->_serverStreamRequest('/grpc.testing.MetricsService/GetAllGauges',
+ $argument,
+ ['\Grpc\Testing\GaugeResponse', 'decode'],
+ $metadata, $options);
+ }
+
+ /**
+ * Returns the value of one gauge
+ * @param \Grpc\Testing\GaugeRequest $argument input argument
+ * @param array $metadata metadata
+ * @param array $options call options
+ */
+ public function GetGauge(\Grpc\Testing\GaugeRequest $argument,
+ $metadata = [], $options = []) {
+ return $this->_simpleRequest('/grpc.testing.MetricsService/GetGauge',
+ $argument,
+ ['\Grpc\Testing\GaugeResponse', 'decode'],
+ $metadata, $options);
+ }
+
+}
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/NoRpcServiceClient.php b/src/php/tests/qps/generated_code/Grpc/Testing/NoRpcServiceClient.php
new file mode 100644
index 0000000..1d58eaf
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/NoRpcServiceClient.php
@@ -0,0 +1,35 @@
+<?php
+// GENERATED CODE -- DO NOT EDIT!
+
+// Original file comments:
+// 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.
+//
+namespace Grpc\Testing;
+
+/**
+ * A service without any rpc defined to test coverage.
+ */
+class NoRpcServiceClient extends \Grpc\BaseStub {
+
+ /**
+ * @param string $hostname hostname
+ * @param array $opts channel options
+ * @param \Grpc\Channel $channel (optional) re-use channel object
+ */
+ public function __construct($hostname, $opts, $channel = null) {
+ parent::__construct($hostname, $opts, $channel);
+ }
+
+}
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/PBEmpty.php b/src/php/tests/qps/generated_code/Grpc/Testing/PBEmpty.php
new file mode 100644
index 0000000..a1fe9df
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/PBEmpty.php
@@ -0,0 +1,30 @@
+<?php
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: src/proto/grpc/testing/empty.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * An empty message that you can re-use to avoid defining duplicated empty
+ * messages in your project. A typical example is to use it as argument or the
+ * return value of a service API. For instance:
+ * service Foo {
+ * rpc Bar (grpc.testing.Empty) returns (grpc.testing.Empty) { };
+ * };
+ *
+ * Generated from protobuf message <code>grpc.testing.Empty</code>
+ */
+class PBEmpty extends \Google\Protobuf\Internal\Message
+{
+
+ public function __construct() {
+ \GPBMetadata\Src\Proto\Grpc\Testing\GPBEmpty::initOnce();
+ parent::__construct();
+ }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/PBVoid.php b/src/php/tests/qps/generated_code/Grpc/Testing/PBVoid.php
new file mode 100644
index 0000000..94cb6c1
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/PBVoid.php
@@ -0,0 +1,23 @@
+<?php
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: src/proto/grpc/testing/control.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Generated from protobuf message <code>grpc.testing.Void</code>
+ */
+class PBVoid extends \Google\Protobuf\Internal\Message
+{
+
+ public function __construct() {
+ \GPBMetadata\Src\Proto\Grpc\Testing\Control::initOnce();
+ parent::__construct();
+ }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ProxyClientServiceClient.php b/src/php/tests/qps/generated_code/Grpc/Testing/ProxyClientServiceClient.php
index 5510b57..c0e3049 100644
--- a/src/php/tests/qps/generated_code/Grpc/Testing/ProxyClientServiceClient.php
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ProxyClientServiceClient.php
@@ -32,11 +32,11 @@
}
/**
- * @param \Grpc\Testing\Void $argument input argument
+ * @param \Grpc\Testing\PBVoid $argument input argument
* @param array $metadata metadata
* @param array $options call options
*/
- public function GetConfig(\Grpc\Testing\Void $argument,
+ public function GetConfig(\Grpc\Testing\PBVoid $argument,
$metadata = [], $options = []) {
return $this->_simpleRequest('/grpc.testing.ProxyClientService/GetConfig',
$argument,
@@ -50,7 +50,7 @@
*/
public function ReportTime($metadata = [], $options = []) {
return $this->_clientStreamRequest('/grpc.testing.ProxyClientService/ReportTime',
- ['\Grpc\Testing\Void','decode'],
+ ['\Grpc\Testing\PBVoid','decode'],
$metadata, $options);
}
@@ -60,7 +60,7 @@
*/
public function ReportHist($metadata = [], $options = []) {
return $this->_clientStreamRequest('/grpc.testing.ProxyClientService/ReportHist',
- ['\Grpc\Testing\Void','decode'],
+ ['\Grpc\Testing\PBVoid','decode'],
$metadata, $options);
}
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ReconnectServiceClient.php b/src/php/tests/qps/generated_code/Grpc/Testing/ReconnectServiceClient.php
new file mode 100644
index 0000000..a1802e9
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ReconnectServiceClient.php
@@ -0,0 +1,64 @@
+<?php
+// GENERATED CODE -- DO NOT EDIT!
+
+// Original file comments:
+// Copyright 2015-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.
+//
+// An integration test service that covers all the method signature permutations
+// of unary/streaming requests/responses.
+//
+namespace Grpc\Testing;
+
+/**
+ * A service used to control reconnect server.
+ */
+class ReconnectServiceClient extends \Grpc\BaseStub {
+
+ /**
+ * @param string $hostname hostname
+ * @param array $opts channel options
+ * @param \Grpc\Channel $channel (optional) re-use channel object
+ */
+ public function __construct($hostname, $opts, $channel = null) {
+ parent::__construct($hostname, $opts, $channel);
+ }
+
+ /**
+ * @param \Grpc\Testing\ReconnectParams $argument input argument
+ * @param array $metadata metadata
+ * @param array $options call options
+ */
+ public function Start(\Grpc\Testing\ReconnectParams $argument,
+ $metadata = [], $options = []) {
+ return $this->_simpleRequest('/grpc.testing.ReconnectService/Start',
+ $argument,
+ ['\Grpc\Testing\PBEmpty', 'decode'],
+ $metadata, $options);
+ }
+
+ /**
+ * @param \Grpc\Testing\PBEmpty $argument input argument
+ * @param array $metadata metadata
+ * @param array $options call options
+ */
+ public function Stop(\Grpc\Testing\PBEmpty $argument,
+ $metadata = [], $options = []) {
+ return $this->_simpleRequest('/grpc.testing.ReconnectService/Stop',
+ $argument,
+ ['\Grpc\Testing\ReconnectInfo', 'decode'],
+ $metadata, $options);
+ }
+
+}
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ReportQpsScenarioServiceClient.php b/src/php/tests/qps/generated_code/Grpc/Testing/ReportQpsScenarioServiceClient.php
index 72d44ff..3abb5ab 100644
--- a/src/php/tests/qps/generated_code/Grpc/Testing/ReportQpsScenarioServiceClient.php
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ReportQpsScenarioServiceClient.php
@@ -43,7 +43,7 @@
$metadata = [], $options = []) {
return $this->_simpleRequest('/grpc.testing.ReportQpsScenarioService/ReportScenario',
$argument,
- ['\Grpc\Testing\Void', 'decode'],
+ ['\Grpc\Testing\PBVoid', 'decode'],
$metadata, $options);
}
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/Request.php b/src/php/tests/qps/generated_code/Grpc/Testing/Request.php
new file mode 100644
index 0000000..6a20f6a
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/Request.php
@@ -0,0 +1,23 @@
+<?php
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: src/proto/grpc/testing/compiler_test.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Generated from protobuf message <code>grpc.testing.Request</code>
+ */
+class Request extends \Google\Protobuf\Internal\Message
+{
+
+ public function __construct() {
+ \GPBMetadata\Src\Proto\Grpc\Testing\CompilerTest::initOnce();
+ parent::__construct();
+ }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/RequestParams.php b/src/php/tests/qps/generated_code/Grpc/Testing/RequestParams.php
new file mode 100644
index 0000000..f01f50d
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/RequestParams.php
@@ -0,0 +1,431 @@
+<?php
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: src/proto/grpc/testing/echo_messages.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Generated from protobuf message <code>grpc.testing.RequestParams</code>
+ */
+class RequestParams extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * Generated from protobuf field <code>bool echo_deadline = 1;</code>
+ */
+ private $echo_deadline = false;
+ /**
+ * Generated from protobuf field <code>int32 client_cancel_after_us = 2;</code>
+ */
+ private $client_cancel_after_us = 0;
+ /**
+ * Generated from protobuf field <code>int32 server_cancel_after_us = 3;</code>
+ */
+ private $server_cancel_after_us = 0;
+ /**
+ * Generated from protobuf field <code>bool echo_metadata = 4;</code>
+ */
+ private $echo_metadata = false;
+ /**
+ * Generated from protobuf field <code>bool check_auth_context = 5;</code>
+ */
+ private $check_auth_context = false;
+ /**
+ * Generated from protobuf field <code>int32 response_message_length = 6;</code>
+ */
+ private $response_message_length = 0;
+ /**
+ * Generated from protobuf field <code>bool echo_peer = 7;</code>
+ */
+ private $echo_peer = false;
+ /**
+ * will force check_auth_context.
+ *
+ * Generated from protobuf field <code>string expected_client_identity = 8;</code>
+ */
+ private $expected_client_identity = '';
+ /**
+ * Generated from protobuf field <code>bool skip_cancelled_check = 9;</code>
+ */
+ private $skip_cancelled_check = false;
+ /**
+ * Generated from protobuf field <code>string expected_transport_security_type = 10;</code>
+ */
+ private $expected_transport_security_type = '';
+ /**
+ * Generated from protobuf field <code>.grpc.testing.DebugInfo debug_info = 11;</code>
+ */
+ private $debug_info = null;
+ /**
+ * Server should not see a request with this set.
+ *
+ * Generated from protobuf field <code>bool server_die = 12;</code>
+ */
+ private $server_die = false;
+ /**
+ * Generated from protobuf field <code>string binary_error_details = 13;</code>
+ */
+ private $binary_error_details = '';
+ /**
+ * Generated from protobuf field <code>.grpc.testing.ErrorStatus expected_error = 14;</code>
+ */
+ private $expected_error = null;
+ /**
+ * Amount to sleep when invoking server
+ *
+ * Generated from protobuf field <code>int32 server_sleep_us = 15;</code>
+ */
+ private $server_sleep_us = 0;
+
+ public function __construct() {
+ \GPBMetadata\Src\Proto\Grpc\Testing\EchoMessages::initOnce();
+ parent::__construct();
+ }
+
+ /**
+ * Generated from protobuf field <code>bool echo_deadline = 1;</code>
+ * @return bool
+ */
+ public function getEchoDeadline()
+ {
+ return $this->echo_deadline;
+ }
+
+ /**
+ * Generated from protobuf field <code>bool echo_deadline = 1;</code>
+ * @param bool $var
+ * @return $this
+ */
+ public function setEchoDeadline($var)
+ {
+ GPBUtil::checkBool($var);
+ $this->echo_deadline = $var;
+
+ return $this;
+ }
+
+ /**
+ * Generated from protobuf field <code>int32 client_cancel_after_us = 2;</code>
+ * @return int
+ */
+ public function getClientCancelAfterUs()
+ {
+ return $this->client_cancel_after_us;
+ }
+
+ /**
+ * Generated from protobuf field <code>int32 client_cancel_after_us = 2;</code>
+ * @param int $var
+ * @return $this
+ */
+ public function setClientCancelAfterUs($var)
+ {
+ GPBUtil::checkInt32($var);
+ $this->client_cancel_after_us = $var;
+
+ return $this;
+ }
+
+ /**
+ * Generated from protobuf field <code>int32 server_cancel_after_us = 3;</code>
+ * @return int
+ */
+ public function getServerCancelAfterUs()
+ {
+ return $this->server_cancel_after_us;
+ }
+
+ /**
+ * Generated from protobuf field <code>int32 server_cancel_after_us = 3;</code>
+ * @param int $var
+ * @return $this
+ */
+ public function setServerCancelAfterUs($var)
+ {
+ GPBUtil::checkInt32($var);
+ $this->server_cancel_after_us = $var;
+
+ return $this;
+ }
+
+ /**
+ * Generated from protobuf field <code>bool echo_metadata = 4;</code>
+ * @return bool
+ */
+ public function getEchoMetadata()
+ {
+ return $this->echo_metadata;
+ }
+
+ /**
+ * Generated from protobuf field <code>bool echo_metadata = 4;</code>
+ * @param bool $var
+ * @return $this
+ */
+ public function setEchoMetadata($var)
+ {
+ GPBUtil::checkBool($var);
+ $this->echo_metadata = $var;
+
+ return $this;
+ }
+
+ /**
+ * Generated from protobuf field <code>bool check_auth_context = 5;</code>
+ * @return bool
+ */
+ public function getCheckAuthContext()
+ {
+ return $this->check_auth_context;
+ }
+
+ /**
+ * Generated from protobuf field <code>bool check_auth_context = 5;</code>
+ * @param bool $var
+ * @return $this
+ */
+ public function setCheckAuthContext($var)
+ {
+ GPBUtil::checkBool($var);
+ $this->check_auth_context = $var;
+
+ return $this;
+ }
+
+ /**
+ * Generated from protobuf field <code>int32 response_message_length = 6;</code>
+ * @return int
+ */
+ public function getResponseMessageLength()
+ {
+ return $this->response_message_length;
+ }
+
+ /**
+ * Generated from protobuf field <code>int32 response_message_length = 6;</code>
+ * @param int $var
+ * @return $this
+ */
+ public function setResponseMessageLength($var)
+ {
+ GPBUtil::checkInt32($var);
+ $this->response_message_length = $var;
+
+ return $this;
+ }
+
+ /**
+ * Generated from protobuf field <code>bool echo_peer = 7;</code>
+ * @return bool
+ */
+ public function getEchoPeer()
+ {
+ return $this->echo_peer;
+ }
+
+ /**
+ * Generated from protobuf field <code>bool echo_peer = 7;</code>
+ * @param bool $var
+ * @return $this
+ */
+ public function setEchoPeer($var)
+ {
+ GPBUtil::checkBool($var);
+ $this->echo_peer = $var;
+
+ return $this;
+ }
+
+ /**
+ * will force check_auth_context.
+ *
+ * Generated from protobuf field <code>string expected_client_identity = 8;</code>
+ * @return string
+ */
+ public function getExpectedClientIdentity()
+ {
+ return $this->expected_client_identity;
+ }
+
+ /**
+ * will force check_auth_context.
+ *
+ * Generated from protobuf field <code>string expected_client_identity = 8;</code>
+ * @param string $var
+ * @return $this
+ */
+ public function setExpectedClientIdentity($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->expected_client_identity = $var;
+
+ return $this;
+ }
+
+ /**
+ * Generated from protobuf field <code>bool skip_cancelled_check = 9;</code>
+ * @return bool
+ */
+ public function getSkipCancelledCheck()
+ {
+ return $this->skip_cancelled_check;
+ }
+
+ /**
+ * Generated from protobuf field <code>bool skip_cancelled_check = 9;</code>
+ * @param bool $var
+ * @return $this
+ */
+ public function setSkipCancelledCheck($var)
+ {
+ GPBUtil::checkBool($var);
+ $this->skip_cancelled_check = $var;
+
+ return $this;
+ }
+
+ /**
+ * Generated from protobuf field <code>string expected_transport_security_type = 10;</code>
+ * @return string
+ */
+ public function getExpectedTransportSecurityType()
+ {
+ return $this->expected_transport_security_type;
+ }
+
+ /**
+ * Generated from protobuf field <code>string expected_transport_security_type = 10;</code>
+ * @param string $var
+ * @return $this
+ */
+ public function setExpectedTransportSecurityType($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->expected_transport_security_type = $var;
+
+ return $this;
+ }
+
+ /**
+ * Generated from protobuf field <code>.grpc.testing.DebugInfo debug_info = 11;</code>
+ * @return \Grpc\Testing\DebugInfo
+ */
+ public function getDebugInfo()
+ {
+ return $this->debug_info;
+ }
+
+ /**
+ * Generated from protobuf field <code>.grpc.testing.DebugInfo debug_info = 11;</code>
+ * @param \Grpc\Testing\DebugInfo $var
+ * @return $this
+ */
+ public function setDebugInfo($var)
+ {
+ GPBUtil::checkMessage($var, \Grpc\Testing\DebugInfo::class);
+ $this->debug_info = $var;
+
+ return $this;
+ }
+
+ /**
+ * Server should not see a request with this set.
+ *
+ * Generated from protobuf field <code>bool server_die = 12;</code>
+ * @return bool
+ */
+ public function getServerDie()
+ {
+ return $this->server_die;
+ }
+
+ /**
+ * Server should not see a request with this set.
+ *
+ * Generated from protobuf field <code>bool server_die = 12;</code>
+ * @param bool $var
+ * @return $this
+ */
+ public function setServerDie($var)
+ {
+ GPBUtil::checkBool($var);
+ $this->server_die = $var;
+
+ return $this;
+ }
+
+ /**
+ * Generated from protobuf field <code>string binary_error_details = 13;</code>
+ * @return string
+ */
+ public function getBinaryErrorDetails()
+ {
+ return $this->binary_error_details;
+ }
+
+ /**
+ * Generated from protobuf field <code>string binary_error_details = 13;</code>
+ * @param string $var
+ * @return $this
+ */
+ public function setBinaryErrorDetails($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->binary_error_details = $var;
+
+ return $this;
+ }
+
+ /**
+ * Generated from protobuf field <code>.grpc.testing.ErrorStatus expected_error = 14;</code>
+ * @return \Grpc\Testing\ErrorStatus
+ */
+ public function getExpectedError()
+ {
+ return $this->expected_error;
+ }
+
+ /**
+ * Generated from protobuf field <code>.grpc.testing.ErrorStatus expected_error = 14;</code>
+ * @param \Grpc\Testing\ErrorStatus $var
+ * @return $this
+ */
+ public function setExpectedError($var)
+ {
+ GPBUtil::checkMessage($var, \Grpc\Testing\ErrorStatus::class);
+ $this->expected_error = $var;
+
+ return $this;
+ }
+
+ /**
+ * Amount to sleep when invoking server
+ *
+ * Generated from protobuf field <code>int32 server_sleep_us = 15;</code>
+ * @return int
+ */
+ public function getServerSleepUs()
+ {
+ return $this->server_sleep_us;
+ }
+
+ /**
+ * Amount to sleep when invoking server
+ *
+ * Generated from protobuf field <code>int32 server_sleep_us = 15;</code>
+ * @param int $var
+ * @return $this
+ */
+ public function setServerSleepUs($var)
+ {
+ GPBUtil::checkInt32($var);
+ $this->server_sleep_us = $var;
+
+ return $this;
+ }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/Response.php b/src/php/tests/qps/generated_code/Grpc/Testing/Response.php
new file mode 100644
index 0000000..7925a7d
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/Response.php
@@ -0,0 +1,23 @@
+<?php
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: src/proto/grpc/testing/compiler_test.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Generated from protobuf message <code>grpc.testing.Response</code>
+ */
+class Response extends \Google\Protobuf\Internal\Message
+{
+
+ public function __construct() {
+ \GPBMetadata\Src\Proto\Grpc\Testing\CompilerTest::initOnce();
+ parent::__construct();
+ }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ResponseParams.php b/src/php/tests/qps/generated_code/Grpc/Testing/ResponseParams.php
new file mode 100644
index 0000000..d20f922
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ResponseParams.php
@@ -0,0 +1,101 @@
+<?php
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: src/proto/grpc/testing/echo_messages.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Generated from protobuf message <code>grpc.testing.ResponseParams</code>
+ */
+class ResponseParams extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * Generated from protobuf field <code>int64 request_deadline = 1;</code>
+ */
+ private $request_deadline = 0;
+ /**
+ * Generated from protobuf field <code>string host = 2;</code>
+ */
+ private $host = '';
+ /**
+ * Generated from protobuf field <code>string peer = 3;</code>
+ */
+ private $peer = '';
+
+ public function __construct() {
+ \GPBMetadata\Src\Proto\Grpc\Testing\EchoMessages::initOnce();
+ parent::__construct();
+ }
+
+ /**
+ * Generated from protobuf field <code>int64 request_deadline = 1;</code>
+ * @return int|string
+ */
+ public function getRequestDeadline()
+ {
+ return $this->request_deadline;
+ }
+
+ /**
+ * Generated from protobuf field <code>int64 request_deadline = 1;</code>
+ * @param int|string $var
+ * @return $this
+ */
+ public function setRequestDeadline($var)
+ {
+ GPBUtil::checkInt64($var);
+ $this->request_deadline = $var;
+
+ return $this;
+ }
+
+ /**
+ * Generated from protobuf field <code>string host = 2;</code>
+ * @return string
+ */
+ public function getHost()
+ {
+ return $this->host;
+ }
+
+ /**
+ * Generated from protobuf field <code>string host = 2;</code>
+ * @param string $var
+ * @return $this
+ */
+ public function setHost($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->host = $var;
+
+ return $this;
+ }
+
+ /**
+ * Generated from protobuf field <code>string peer = 3;</code>
+ * @return string
+ */
+ public function getPeer()
+ {
+ return $this->peer;
+ }
+
+ /**
+ * Generated from protobuf field <code>string peer = 3;</code>
+ * @param string $var
+ * @return $this
+ */
+ public function setPeer($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->peer = $var;
+
+ return $this;
+ }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ServiceAClient.php b/src/php/tests/qps/generated_code/Grpc/Testing/ServiceAClient.php
new file mode 100644
index 0000000..df469cb
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ServiceAClient.php
@@ -0,0 +1,97 @@
+<?php
+// GENERATED CODE -- DO NOT EDIT!
+
+// Original file comments:
+// 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.
+//
+// File detached comment 1
+//
+// File detached comment 2
+//
+// File leading comment 1
+namespace Grpc\Testing;
+
+/**
+ * ServiceA detached comment 1
+ *
+ * ServiceA detached comment 2
+ *
+ * ServiceA leading comment 1
+ */
+class ServiceAClient extends \Grpc\BaseStub {
+
+ /**
+ * @param string $hostname hostname
+ * @param array $opts channel options
+ * @param \Grpc\Channel $channel (optional) re-use channel object
+ */
+ public function __construct($hostname, $opts, $channel = null) {
+ parent::__construct($hostname, $opts, $channel);
+ }
+
+ /**
+ * MethodA1 leading comment 1
+ * @param \Grpc\Testing\Request $argument input argument
+ * @param array $metadata metadata
+ * @param array $options call options
+ */
+ public function MethodA1(\Grpc\Testing\Request $argument,
+ $metadata = [], $options = []) {
+ return $this->_simpleRequest('/grpc.testing.ServiceA/MethodA1',
+ $argument,
+ ['\Grpc\Testing\Response', 'decode'],
+ $metadata, $options);
+ }
+
+ /**
+ * MethodA2 detached leading comment 1
+ *
+ * Method A2 leading comment 1
+ * Method A2 leading comment 2
+ * @param array $metadata metadata
+ * @param array $options call options
+ */
+ public function MethodA2($metadata = [], $options = []) {
+ return $this->_clientStreamRequest('/grpc.testing.ServiceA/MethodA2',
+ ['\Grpc\Testing\Response','decode'],
+ $metadata, $options);
+ }
+
+ /**
+ * Method A3 leading comment 1
+ * @param \Grpc\Testing\Request $argument input argument
+ * @param array $metadata metadata
+ * @param array $options call options
+ */
+ public function MethodA3(\Grpc\Testing\Request $argument,
+ $metadata = [], $options = []) {
+ return $this->_serverStreamRequest('/grpc.testing.ServiceA/MethodA3',
+ $argument,
+ ['\Grpc\Testing\Response', 'decode'],
+ $metadata, $options);
+ }
+
+ /**
+ * Method A4 leading comment 1
+ * @param array $metadata metadata
+ * @param array $options call options
+ */
+ public function MethodA4($metadata = [], $options = []) {
+ return $this->_bidiRequest('/grpc.testing.ServiceA/MethodA4',
+ ['\Grpc\Testing\Response','decode'],
+ $metadata, $options);
+ }
+
+}
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ServiceBClient.php b/src/php/tests/qps/generated_code/Grpc/Testing/ServiceBClient.php
new file mode 100644
index 0000000..54acf63
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ServiceBClient.php
@@ -0,0 +1,54 @@
+<?php
+// GENERATED CODE -- DO NOT EDIT!
+
+// Original file comments:
+// 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.
+//
+// File detached comment 1
+//
+// File detached comment 2
+//
+// File leading comment 1
+namespace Grpc\Testing;
+
+/**
+ * ServiceB leading comment 1
+ */
+class ServiceBClient extends \Grpc\BaseStub {
+
+ /**
+ * @param string $hostname hostname
+ * @param array $opts channel options
+ * @param \Grpc\Channel $channel (optional) re-use channel object
+ */
+ public function __construct($hostname, $opts, $channel = null) {
+ parent::__construct($hostname, $opts, $channel);
+ }
+
+ /**
+ * MethodB1 leading comment 1
+ * @param \Grpc\Testing\Request $argument input argument
+ * @param array $metadata metadata
+ * @param array $options call options
+ */
+ public function MethodB1(\Grpc\Testing\Request $argument,
+ $metadata = [], $options = []) {
+ return $this->_simpleRequest('/grpc.testing.ServiceB/MethodB1',
+ $argument,
+ ['\Grpc\Testing\Response', 'decode'],
+ $metadata, $options);
+ }
+
+}
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/TestServiceClient.php b/src/php/tests/qps/generated_code/Grpc/Testing/TestServiceClient.php
new file mode 100644
index 0000000..7da9713
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/TestServiceClient.php
@@ -0,0 +1,152 @@
+<?php
+// GENERATED CODE -- DO NOT EDIT!
+
+// Original file comments:
+// Copyright 2015-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.
+//
+// An integration test service that covers all the method signature permutations
+// of unary/streaming requests/responses.
+//
+namespace Grpc\Testing;
+
+/**
+ * A simple service to test the various types of RPCs and experiment with
+ * performance with various types of payload.
+ */
+class TestServiceClient extends \Grpc\BaseStub {
+
+ /**
+ * @param string $hostname hostname
+ * @param array $opts channel options
+ * @param \Grpc\Channel $channel (optional) re-use channel object
+ */
+ public function __construct($hostname, $opts, $channel = null) {
+ parent::__construct($hostname, $opts, $channel);
+ }
+
+ /**
+ * One empty request followed by one empty response.
+ * @param \Grpc\Testing\PBEmpty $argument input argument
+ * @param array $metadata metadata
+ * @param array $options call options
+ */
+ public function EmptyCall(\Grpc\Testing\PBEmpty $argument,
+ $metadata = [], $options = []) {
+ return $this->_simpleRequest('/grpc.testing.TestService/EmptyCall',
+ $argument,
+ ['\Grpc\Testing\PBEmpty', 'decode'],
+ $metadata, $options);
+ }
+
+ /**
+ * One request followed by one response.
+ * @param \Grpc\Testing\SimpleRequest $argument input argument
+ * @param array $metadata metadata
+ * @param array $options call options
+ */
+ public function UnaryCall(\Grpc\Testing\SimpleRequest $argument,
+ $metadata = [], $options = []) {
+ return $this->_simpleRequest('/grpc.testing.TestService/UnaryCall',
+ $argument,
+ ['\Grpc\Testing\SimpleResponse', 'decode'],
+ $metadata, $options);
+ }
+
+ /**
+ * One request followed by one response. Response has cache control
+ * headers set such that a caching HTTP proxy (such as GFE) can
+ * satisfy subsequent requests.
+ * @param \Grpc\Testing\SimpleRequest $argument input argument
+ * @param array $metadata metadata
+ * @param array $options call options
+ */
+ public function CacheableUnaryCall(\Grpc\Testing\SimpleRequest $argument,
+ $metadata = [], $options = []) {
+ return $this->_simpleRequest('/grpc.testing.TestService/CacheableUnaryCall',
+ $argument,
+ ['\Grpc\Testing\SimpleResponse', 'decode'],
+ $metadata, $options);
+ }
+
+ /**
+ * One request followed by a sequence of responses (streamed download).
+ * The server returns the payload with client desired type and sizes.
+ * @param \Grpc\Testing\StreamingOutputCallRequest $argument input argument
+ * @param array $metadata metadata
+ * @param array $options call options
+ */
+ public function StreamingOutputCall(\Grpc\Testing\StreamingOutputCallRequest $argument,
+ $metadata = [], $options = []) {
+ return $this->_serverStreamRequest('/grpc.testing.TestService/StreamingOutputCall',
+ $argument,
+ ['\Grpc\Testing\StreamingOutputCallResponse', 'decode'],
+ $metadata, $options);
+ }
+
+ /**
+ * A sequence of requests followed by one response (streamed upload).
+ * The server returns the aggregated size of client payload as the result.
+ * @param array $metadata metadata
+ * @param array $options call options
+ */
+ public function StreamingInputCall($metadata = [], $options = []) {
+ return $this->_clientStreamRequest('/grpc.testing.TestService/StreamingInputCall',
+ ['\Grpc\Testing\StreamingInputCallResponse','decode'],
+ $metadata, $options);
+ }
+
+ /**
+ * A sequence of requests with each request served by the server immediately.
+ * As one request could lead to multiple responses, this interface
+ * demonstrates the idea of full duplexing.
+ * @param array $metadata metadata
+ * @param array $options call options
+ */
+ public function FullDuplexCall($metadata = [], $options = []) {
+ return $this->_bidiRequest('/grpc.testing.TestService/FullDuplexCall',
+ ['\Grpc\Testing\StreamingOutputCallResponse','decode'],
+ $metadata, $options);
+ }
+
+ /**
+ * A sequence of requests followed by a sequence of responses.
+ * The server buffers all the client requests and then serves them in order. A
+ * stream of responses are returned to the client when the server starts with
+ * first request.
+ * @param array $metadata metadata
+ * @param array $options call options
+ */
+ public function HalfDuplexCall($metadata = [], $options = []) {
+ return $this->_bidiRequest('/grpc.testing.TestService/HalfDuplexCall',
+ ['\Grpc\Testing\StreamingOutputCallResponse','decode'],
+ $metadata, $options);
+ }
+
+ /**
+ * The test server will not implement this method. It will be used
+ * to test the behavior when clients call unimplemented methods.
+ * @param \Grpc\Testing\PBEmpty $argument input argument
+ * @param array $metadata metadata
+ * @param array $options call options
+ */
+ public function UnimplementedCall(\Grpc\Testing\PBEmpty $argument,
+ $metadata = [], $options = []) {
+ return $this->_simpleRequest('/grpc.testing.TestService/UnimplementedCall',
+ $argument,
+ ['\Grpc\Testing\PBEmpty', 'decode'],
+ $metadata, $options);
+ }
+
+}
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/UnimplementedEchoServiceClient.php b/src/php/tests/qps/generated_code/Grpc/Testing/UnimplementedEchoServiceClient.php
new file mode 100644
index 0000000..fee0daa
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/UnimplementedEchoServiceClient.php
@@ -0,0 +1,47 @@
+<?php
+// GENERATED CODE -- DO NOT EDIT!
+
+// Original file comments:
+// 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.
+//
+namespace Grpc\Testing;
+
+/**
+ */
+class UnimplementedEchoServiceClient extends \Grpc\BaseStub {
+
+ /**
+ * @param string $hostname hostname
+ * @param array $opts channel options
+ * @param \Grpc\Channel $channel (optional) re-use channel object
+ */
+ public function __construct($hostname, $opts, $channel = null) {
+ parent::__construct($hostname, $opts, $channel);
+ }
+
+ /**
+ * @param \Grpc\Testing\EchoRequest $argument input argument
+ * @param array $metadata metadata
+ * @param array $options call options
+ */
+ public function Unimplemented(\Grpc\Testing\EchoRequest $argument,
+ $metadata = [], $options = []) {
+ return $this->_simpleRequest('/grpc.testing.UnimplementedEchoService/Unimplemented',
+ $argument,
+ ['\Grpc\Testing\EchoResponse', 'decode'],
+ $metadata, $options);
+ }
+
+}
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/UnimplementedServiceClient.php b/src/php/tests/qps/generated_code/Grpc/Testing/UnimplementedServiceClient.php
new file mode 100644
index 0000000..53b2020
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/UnimplementedServiceClient.php
@@ -0,0 +1,53 @@
+<?php
+// GENERATED CODE -- DO NOT EDIT!
+
+// Original file comments:
+// Copyright 2015-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.
+//
+// An integration test service that covers all the method signature permutations
+// of unary/streaming requests/responses.
+//
+namespace Grpc\Testing;
+
+/**
+ * A simple service NOT implemented at servers so clients can test for
+ * that case.
+ */
+class UnimplementedServiceClient extends \Grpc\BaseStub {
+
+ /**
+ * @param string $hostname hostname
+ * @param array $opts channel options
+ * @param \Grpc\Channel $channel (optional) re-use channel object
+ */
+ public function __construct($hostname, $opts, $channel = null) {
+ parent::__construct($hostname, $opts, $channel);
+ }
+
+ /**
+ * A call that no server should implement
+ * @param \Grpc\Testing\PBEmpty $argument input argument
+ * @param array $metadata metadata
+ * @param array $options call options
+ */
+ public function UnimplementedCall(\Grpc\Testing\PBEmpty $argument,
+ $metadata = [], $options = []) {
+ return $this->_simpleRequest('/grpc.testing.UnimplementedService/UnimplementedCall',
+ $argument,
+ ['\Grpc\Testing\PBEmpty', 'decode'],
+ $metadata, $options);
+ }
+
+}
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/WorkerServiceClient.php b/src/php/tests/qps/generated_code/Grpc/Testing/WorkerServiceClient.php
index 98c244f..366e365 100644
--- a/src/php/tests/qps/generated_code/Grpc/Testing/WorkerServiceClient.php
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/WorkerServiceClient.php
@@ -81,15 +81,15 @@
/**
* Quit this worker
- * @param \Grpc\Testing\Void $argument input argument
+ * @param \Grpc\Testing\PBVoid $argument input argument
* @param array $metadata metadata
* @param array $options call options
*/
- public function QuitWorker(\Grpc\Testing\Void $argument,
+ public function QuitWorker(\Grpc\Testing\PBVoid $argument,
$metadata = [], $options = []) {
return $this->_simpleRequest('/grpc.testing.WorkerService/QuitWorker',
$argument,
- ['\Grpc\Testing\Void', 'decode'],
+ ['\Grpc\Testing\PBVoid', 'decode'],
$metadata, $options);
}
diff --git a/src/php/tests/unit_tests/InterceptorTest.php b/src/php/tests/unit_tests/InterceptorTest.php
new file mode 100644
index 0000000..08f5abb
--- /dev/null
+++ b/src/php/tests/unit_tests/InterceptorTest.php
@@ -0,0 +1,427 @@
+<?php
+/*
+ *
+ * Copyright 2018 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.
+ *
+ */
+/**
+ * Interface exported by the server.
+ */
+require_once(dirname(__FILE__).'/../../lib/Grpc/BaseStub.php');
+require_once(dirname(__FILE__).'/../../lib/Grpc/AbstractCall.php');
+require_once(dirname(__FILE__).'/../../lib/Grpc/UnaryCall.php');
+require_once(dirname(__FILE__).'/../../lib/Grpc/ClientStreamingCall.php');
+require_once(dirname(__FILE__).'/../../lib/Grpc/Interceptor.php');
+require_once(dirname(__FILE__).'/../../lib/Grpc/Internal/InterceptorChannel.php');
+
+class SimpleRequest
+{
+ private $data;
+ public function __construct($data)
+ {
+ $this->data = $data;
+ }
+ public function setData($data)
+ {
+ $this->data = $data;
+ }
+ public function serializeToString()
+ {
+ return $this->data;
+ }
+}
+
+class InterceptorClient extends Grpc\BaseStub
+{
+
+ /**
+ * @param string $hostname hostname
+ * @param array $opts channel options
+ * @param Channel|InterceptorChannel $channel (optional) re-use channel object
+ */
+ public function __construct($hostname, $opts, $channel = null)
+ {
+ parent::__construct($hostname, $opts, $channel);
+ }
+
+ /**
+ * A simple RPC.
+ * @param \Routeguide\Point $argument input argument
+ * @param array $metadata metadata
+ * @param array $options call options
+ */
+ public function UnaryCall(
+ SimpleRequest $argument,
+ $metadata = [],
+ $options = []
+ ) {
+ return $this->_simpleRequest(
+ '/dummy_method',
+ $argument,
+ [],
+ $metadata,
+ $options
+ );
+ }
+
+ /**
+ * A client-to-server streaming RPC.
+ * @param array $metadata metadata
+ * @param array $options call options
+ */
+ public function StreamCall(
+ $metadata = [],
+ $options = []
+ ) {
+ return $this->_clientStreamRequest('/dummy_method', [], $metadata, $options);
+ }
+}
+
+
+class ChangeMetadataInterceptor extends Grpc\Interceptor
+{
+ public function interceptUnaryUnary($method,
+ $argument,
+ array $metadata = [],
+ array $options = [],
+ $continuation)
+ {
+ $metadata["foo"] = array('interceptor_from_unary_request');
+ return $continuation($method, $argument, $metadata, $options);
+ }
+ public function interceptStreamUnary($method, array $metadata = [], array $options = [], $continuation)
+ {
+ $metadata["foo"] = array('interceptor_from_stream_request');
+ return $continuation($method, $metadata, $options);
+ }
+}
+
+class ChangeMetadataInterceptor2 extends Grpc\Interceptor
+{
+ public function interceptUnaryUnary($method,
+ $argument,
+ array $metadata = [],
+ array $options = [],
+ $continuation)
+ {
+ if (array_key_exists('foo', $metadata)) {
+ $metadata['bar'] = array('ChangeMetadataInterceptor should be executed first');
+ } else {
+ $metadata["bar"] = array('interceptor_from_unary_request');
+ }
+ return $continuation($method, $argument, $metadata, $options);
+ }
+ public function interceptStreamUnary($method,
+ array $metadata = [],
+ array $options = [],
+ $continuation)
+ {
+ if (array_key_exists('foo', $metadata)) {
+ $metadata['bar'] = array('ChangeMetadataInterceptor should be executed first');
+ } else {
+ $metadata["bar"] = array('interceptor_from_stream_request');
+ }
+ return $continuation($method, $metadata, $options);
+ }
+}
+
+class ChangeRequestCall
+{
+ private $call;
+
+ public function __construct($call)
+ {
+ $this->call = $call;
+ }
+ public function getCall()
+ {
+ return $this->call;
+ }
+
+ public function write($request)
+ {
+ $request->setData('intercepted_stream_request');
+ $this->getCall()->write($request);
+ }
+
+ public function wait()
+ {
+ return $this->getCall()->wait();
+ }
+}
+
+class ChangeRequestInterceptor extends Grpc\Interceptor
+{
+ public function interceptUnaryUnary($method,
+ $argument,
+ array $metadata = [],
+ array $options = [],
+ $continuation)
+ {
+ $argument->setData('intercepted_unary_request');
+ return $continuation($method, $argument, $metadata, $options);
+ }
+ public function interceptStreamUnary($method, array $metadata = [], array $options = [], $continuation)
+ {
+ return new ChangeRequestCall(
+ $continuation($method, $metadata, $options)
+ );
+ }
+}
+
+class StopCallInterceptor extends Grpc\Interceptor
+{
+ public function interceptUnaryUnary($method,
+ $argument,
+ array $metadata = [],
+ array $options = [],
+ $continuation)
+ {
+ $metadata["foo"] = array('interceptor_from_request_response');
+ }
+ public function interceptStreamUnary($method,
+ array $metadata = [],
+ array $options = [],
+ $continuation)
+ {
+ $metadata["foo"] = array('interceptor_from_request_response');
+ }
+}
+
+class InterceptorTest extends PHPUnit_Framework_TestCase
+{
+ public function setUp()
+ {
+ $this->server = new Grpc\Server([]);
+ $this->port = $this->server->addHttp2Port('0.0.0.0:0');
+ $this->channel = new Grpc\Channel('localhost:'.$this->port, ['credentials' => Grpc\ChannelCredentials::createInsecure()]);
+ $this->server->start();
+ }
+
+ public function tearDown()
+ {
+ $this->channel->close();
+ }
+
+
+ public function testClientChangeMetadataOneInterceptor()
+ {
+ $req_text = 'client_request';
+ $channel_matadata_interceptor = new ChangeMetadataInterceptor();
+ $intercept_channel = Grpc\Interceptor::intercept($this->channel, $channel_matadata_interceptor);
+ echo "create Client\n";
+ $client = new InterceptorClient('localhost:'.$this->port, [
+ 'credentials' => Grpc\ChannelCredentials::createInsecure(),
+ ], $intercept_channel);
+ echo "create Call\n";
+ $req = new SimpleRequest($req_text);
+ echo "Call created\n";
+ $unary_call = $client->UnaryCall($req);
+ echo "start call\n";
+ $event = $this->server->requestCall();
+ $this->assertSame('/dummy_method', $event->method);
+ $this->assertSame(['interceptor_from_unary_request'], $event->metadata['foo']);
+
+ $stream_call = $client->StreamCall();
+ $stream_call->write($req);
+ $event = $this->server->requestCall();
+ $this->assertSame('/dummy_method', $event->method);
+ $this->assertSame(['interceptor_from_stream_request'], $event->metadata['foo']);
+
+ unset($unary_call);
+ unset($stream_call);
+ unset($server_call);
+ }
+
+ public function testClientChangeMetadataTwoInterceptor()
+ {
+ $req_text = 'client_request';
+ $channel_matadata_interceptor = new ChangeMetadataInterceptor();
+ $channel_matadata_intercepto2 = new ChangeMetadataInterceptor2();
+ // test intercept separately.
+ $intercept_channel1 = Grpc\Interceptor::intercept($this->channel, $channel_matadata_interceptor);
+ $intercept_channel2 = Grpc\Interceptor::intercept($intercept_channel1, $channel_matadata_intercepto2);
+ $client = new InterceptorClient('localhost:'.$this->port, [
+ 'credentials' => Grpc\ChannelCredentials::createInsecure(),
+ ], $intercept_channel2);
+
+ $req = new SimpleRequest($req_text);
+ $unary_call = $client->UnaryCall($req);
+ $event = $this->server->requestCall();
+ $this->assertSame('/dummy_method', $event->method);
+ $this->assertSame(['interceptor_from_unary_request'], $event->metadata['foo']);
+ $this->assertSame(['interceptor_from_unary_request'], $event->metadata['bar']);
+
+ $stream_call = $client->StreamCall();
+ $stream_call->write($req);
+ $event = $this->server->requestCall();
+ $this->assertSame('/dummy_method', $event->method);
+ $this->assertSame(['interceptor_from_stream_request'], $event->metadata['foo']);
+ $this->assertSame(['interceptor_from_stream_request'], $event->metadata['bar']);
+
+ unset($unary_call);
+ unset($stream_call);
+ unset($server_call);
+
+ // test intercept by array.
+ $intercept_channel3 = Grpc\Interceptor::intercept($this->channel,
+ [$channel_matadata_intercepto2, $channel_matadata_interceptor]);
+ $client = new InterceptorClient('localhost:'.$this->port, [
+ 'credentials' => Grpc\ChannelCredentials::createInsecure(),
+ ], $intercept_channel3);
+
+ $req = new SimpleRequest($req_text);
+ $unary_call = $client->UnaryCall($req);
+ $event = $this->server->requestCall();
+ $this->assertSame('/dummy_method', $event->method);
+ $this->assertSame(['interceptor_from_unary_request'], $event->metadata['foo']);
+ $this->assertSame(['interceptor_from_unary_request'], $event->metadata['bar']);
+
+ $stream_call = $client->StreamCall();
+ $stream_call->write($req);
+ $event = $this->server->requestCall();
+ $this->assertSame('/dummy_method', $event->method);
+ $this->assertSame(['interceptor_from_stream_request'], $event->metadata['foo']);
+ $this->assertSame(['interceptor_from_stream_request'], $event->metadata['bar']);
+
+ unset($unary_call);
+ unset($stream_call);
+ unset($server_call);
+ }
+
+ public function testClientChangeRequestInterceptor()
+ {
+ $req_text = 'client_request';
+ $change_request_interceptor = new ChangeRequestInterceptor();
+ $intercept_channel = Grpc\Interceptor::intercept($this->channel,
+ $change_request_interceptor);
+ $client = new InterceptorClient('localhost:'.$this->port, [
+ 'credentials' => Grpc\ChannelCredentials::createInsecure(),
+ ], $intercept_channel);
+
+ $req = new SimpleRequest($req_text);
+ $unary_call = $client->UnaryCall($req);
+
+ $event = $this->server->requestCall();
+ $this->assertSame('/dummy_method', $event->method);
+ $server_call = $event->call;
+ $event = $server_call->startBatch([
+ Grpc\OP_SEND_INITIAL_METADATA => [],
+ Grpc\OP_SEND_STATUS_FROM_SERVER => [
+ 'metadata' => [],
+ 'code' => Grpc\STATUS_OK,
+ 'details' => '',
+ ],
+ Grpc\OP_RECV_MESSAGE => true,
+ Grpc\OP_RECV_CLOSE_ON_SERVER => true,
+ ]);
+ $this->assertSame('intercepted_unary_request', $event->message);
+
+ $stream_call = $client->StreamCall();
+ $stream_call->write($req);
+ $event = $this->server->requestCall();
+ $this->assertSame('/dummy_method', $event->method);
+ $server_call = $event->call;
+ $event = $server_call->startBatch([
+ Grpc\OP_SEND_INITIAL_METADATA => [],
+ Grpc\OP_SEND_STATUS_FROM_SERVER => [
+ 'metadata' => [],
+ 'code' => Grpc\STATUS_OK,
+ 'details' => '',
+ ],
+ Grpc\OP_RECV_MESSAGE => true,
+ Grpc\OP_RECV_CLOSE_ON_SERVER => true,
+ ]);
+ $this->assertSame('intercepted_stream_request', $event->message);
+
+ unset($unary_call);
+ unset($stream_call);
+ unset($server_call);
+ }
+
+ public function testClientChangeStopCallInterceptor()
+ {
+ $req_text = 'client_request';
+ $channel_request_interceptor = new StopCallInterceptor();
+ $intercept_channel = Grpc\Interceptor::intercept($this->channel,
+ $channel_request_interceptor);
+ $client = new InterceptorClient('localhost:'.$this->port, [
+ 'credentials' => Grpc\ChannelCredentials::createInsecure(),
+ ], $intercept_channel);
+
+ $req = new SimpleRequest($req_text);
+ $unary_call = $client->UnaryCall($req);
+ $this->assertNull($unary_call);
+
+
+ $stream_call = $client->StreamCall();
+ $this->assertNull($stream_call);
+
+ unset($unary_call);
+ unset($stream_call);
+ unset($server_call);
+ }
+
+ public function testGetInterceptorChannelConnectivityState()
+ {
+ $channel = new Grpc\Channel(
+ 'localhost:0',
+ ['credentials' => Grpc\ChannelCredentials::createInsecure()]
+ );
+ $interceptor_channel = Grpc\Interceptor::intercept($channel, new Grpc\Interceptor());
+ $state = $interceptor_channel->getConnectivityState();
+ $this->assertEquals(0, $state);
+ $channel->close();
+ }
+
+ public function testInterceptorChannelWatchConnectivityState()
+ {
+ $channel = new Grpc\Channel(
+ 'localhost:0',
+ ['credentials' => Grpc\ChannelCredentials::createInsecure()]
+ );
+ $interceptor_channel = Grpc\Interceptor::intercept($channel, new Grpc\Interceptor());
+ $now = Grpc\Timeval::now();
+ $deadline = $now->add(new Grpc\Timeval(100*1000));
+ $state = $interceptor_channel->watchConnectivityState(1, $deadline);
+ $this->assertTrue($state);
+ unset($time);
+ unset($deadline);
+ $channel->close();
+ }
+
+ public function testInterceptorChannelClose()
+ {
+ $channel = new Grpc\Channel(
+ 'localhost:0',
+ ['credentials' => Grpc\ChannelCredentials::createInsecure()]
+ );
+ $interceptor_channel = Grpc\Interceptor::intercept($channel, new Grpc\Interceptor());
+ $this->assertNotNull($interceptor_channel);
+ $channel->close();
+ }
+
+ public function testInterceptorChannelGetTarget()
+ {
+ $channel = new Grpc\Channel(
+ 'localhost:8888',
+ ['credentials' => Grpc\ChannelCredentials::createInsecure()]
+ );
+ $interceptor_channel = Grpc\Interceptor::intercept($channel, new Grpc\Interceptor());
+ $target = $interceptor_channel->getTarget();
+ $this->assertTrue(is_string($target));
+ $channel->close();
+ }
+}
diff --git a/src/php/tests/unit_tests/ServerTest.php b/src/php/tests/unit_tests/ServerTest.php
index fee9f1e..ac6f2f0 100644
--- a/src/php/tests/unit_tests/ServerTest.php
+++ b/src/php/tests/unit_tests/ServerTest.php
@@ -99,6 +99,24 @@
/**
* @expectedException InvalidArgumentException
*/
+ public function testInvalidConstructorWithNumKeyOfArray()
+ {
+ $this->server = new Grpc\Server([10 => '127.0.0.1',
+ 20 => '8080', ]);
+ $this->assertNull($this->server);
+ }
+
+ /**
+ * @expectedException InvalidArgumentException
+ */
+ public function testInvalidConstructorWithList()
+ {
+ $this->server = new Grpc\Server(['127.0.0.1', '8080']);
+ $this->assertNull($this->server);
+ }
+ /**
+ * @expectedException InvalidArgumentException
+ */
public function testInvalidAddHttp2Port()
{
$this->server = new Grpc\Server([]);
diff --git a/src/proto/grpc/health/v1/health.proto b/src/proto/grpc/health/v1/health.proto
index 3fda02c..4b4677b 100644
--- a/src/proto/grpc/health/v1/health.proto
+++ b/src/proto/grpc/health/v1/health.proto
@@ -1,4 +1,4 @@
-// Copyright 2015 gRPC authors.
+// Copyright 2015 The gRPC Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,10 +12,18 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+// The canonical version of this proto can be found at
+// https://github.com/grpc/grpc-proto/blob/master/grpc/health/v1/health.proto
+
syntax = "proto3";
package grpc.health.v1;
+
option csharp_namespace = "Grpc.Health.V1";
+option go_package = "google.golang.org/grpc/health/grpc_health_v1";
+option java_multiple_files = true;
+option java_outer_classname = "HealthProto";
+option java_package = "io.grpc.health.v1";
message HealthCheckRequest {
string service = 1;
diff --git a/src/proto/grpc/testing/BUILD b/src/proto/grpc/testing/BUILD
index 58412ed..16721ff 100644
--- a/src/proto/grpc/testing/BUILD
+++ b/src/proto/grpc/testing/BUILD
@@ -76,11 +76,26 @@
)
grpc_proto_library(
- name = "services_proto",
- srcs = ["services.proto"],
+ name = "benchmark_service_proto",
+ srcs = ["benchmark_service.proto"],
deps = [
- "control_proto",
- "messages_proto",
+ "messages_proto",
+ ],
+)
+
+grpc_proto_library(
+ name = "report_qps_scenario_service_proto",
+ srcs = ["report_qps_scenario_service.proto"],
+ deps = [
+ "control_proto",
+ ],
+)
+
+grpc_proto_library(
+ name = "worker_service_proto",
+ srcs = ["worker_service.proto"],
+ deps = [
+ "control_proto",
],
)
diff --git a/src/proto/grpc/testing/benchmark_service.proto b/src/proto/grpc/testing/benchmark_service.proto
new file mode 100644
index 0000000..63167a8
--- /dev/null
+++ b/src/proto/grpc/testing/benchmark_service.proto
@@ -0,0 +1,44 @@
+// 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.
+
+// An integration test service that covers all the method signature permutations
+// of unary/streaming requests/responses.
+syntax = "proto3";
+
+import "src/proto/grpc/testing/messages.proto";
+
+package grpc.testing;
+
+service BenchmarkService {
+ // One request followed by one response.
+ // The server returns the client payload as-is.
+ rpc UnaryCall(SimpleRequest) returns (SimpleResponse);
+
+ // Repeated sequence of one request followed by one response.
+ // Should be called streaming ping-pong
+ // The server returns the client payload as-is on each response
+ rpc StreamingCall(stream SimpleRequest) returns (stream SimpleResponse);
+
+ // Single-sided unbounded streaming from client to server
+ // The server returns the client payload as-is once the client does WritesDone
+ rpc StreamingFromClient(stream SimpleRequest) returns (SimpleResponse);
+
+ // Single-sided unbounded streaming from server to client
+ // The server repeatedly returns the client payload as-is
+ rpc StreamingFromServer(SimpleRequest) returns (stream SimpleResponse);
+
+ // Two-sided unbounded streaming between server to client
+ // Both sides send the content of their own choice to the other
+ rpc StreamingBothWays(stream SimpleRequest) returns (stream SimpleResponse);
+}
diff --git a/src/proto/grpc/testing/report_qps_scenario_service.proto b/src/proto/grpc/testing/report_qps_scenario_service.proto
new file mode 100644
index 0000000..f4e5c36
--- /dev/null
+++ b/src/proto/grpc/testing/report_qps_scenario_service.proto
@@ -0,0 +1,26 @@
+// 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.
+
+// An integration test service that covers all the method signature permutations
+// of unary/streaming requests/responses.
+syntax = "proto3";
+
+import "src/proto/grpc/testing/control.proto";
+
+package grpc.testing;
+
+service ReportQpsScenarioService {
+ // Report results of a QPS test benchmark scenario.
+ rpc ReportScenario(ScenarioResult) returns (Void);
+}
diff --git a/src/proto/grpc/testing/services.proto b/src/proto/grpc/testing/services.proto
deleted file mode 100644
index 93c21f4..0000000
--- a/src/proto/grpc/testing/services.proto
+++ /dev/null
@@ -1,74 +0,0 @@
-// 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.
-
-// An integration test service that covers all the method signature permutations
-// of unary/streaming requests/responses.
-syntax = "proto3";
-
-import "src/proto/grpc/testing/messages.proto";
-import "src/proto/grpc/testing/control.proto";
-
-package grpc.testing;
-
-service BenchmarkService {
- // One request followed by one response.
- // The server returns the client payload as-is.
- rpc UnaryCall(SimpleRequest) returns (SimpleResponse);
-
- // Repeated sequence of one request followed by one response.
- // Should be called streaming ping-pong
- // The server returns the client payload as-is on each response
- rpc StreamingCall(stream SimpleRequest) returns (stream SimpleResponse);
-
- // Single-sided unbounded streaming from client to server
- // The server returns the client payload as-is once the client does WritesDone
- rpc StreamingFromClient(stream SimpleRequest) returns (SimpleResponse);
-
- // Single-sided unbounded streaming from server to client
- // The server repeatedly returns the client payload as-is
- rpc StreamingFromServer(SimpleRequest) returns (stream SimpleResponse);
-
- // Two-sided unbounded streaming between server to client
- // Both sides send the content of their own choice to the other
- rpc StreamingBothWays(stream SimpleRequest) returns (stream SimpleResponse);
-}
-
-service WorkerService {
- // Start server with specified workload.
- // First request sent specifies the ServerConfig followed by ServerStatus
- // response. After that, a "Mark" can be sent anytime to request the latest
- // stats. Closing the stream will initiate shutdown of the test server
- // and once the shutdown has finished, the OK status is sent to terminate
- // this RPC.
- rpc RunServer(stream ServerArgs) returns (stream ServerStatus);
-
- // Start client with specified workload.
- // First request sent specifies the ClientConfig followed by ClientStatus
- // response. After that, a "Mark" can be sent anytime to request the latest
- // stats. Closing the stream will initiate shutdown of the test client
- // and once the shutdown has finished, the OK status is sent to terminate
- // this RPC.
- rpc RunClient(stream ClientArgs) returns (stream ClientStatus);
-
- // Just return the core count - unary call
- rpc CoreCount(CoreRequest) returns (CoreResponse);
-
- // Quit this worker
- rpc QuitWorker(Void) returns (Void);
-}
-
-service ReportQpsScenarioService {
- // Report results of a QPS test benchmark scenario.
- rpc ReportScenario(ScenarioResult) returns (Void);
-}
diff --git a/src/proto/grpc/testing/worker_service.proto b/src/proto/grpc/testing/worker_service.proto
new file mode 100644
index 0000000..a4cde94
--- /dev/null
+++ b/src/proto/grpc/testing/worker_service.proto
@@ -0,0 +1,45 @@
+// 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.
+
+// An integration test service that covers all the method signature permutations
+// of unary/streaming requests/responses.
+syntax = "proto3";
+
+import "src/proto/grpc/testing/control.proto";
+
+package grpc.testing;
+
+service WorkerService {
+ // Start server with specified workload.
+ // First request sent specifies the ServerConfig followed by ServerStatus
+ // response. After that, a "Mark" can be sent anytime to request the latest
+ // stats. Closing the stream will initiate shutdown of the test server
+ // and once the shutdown has finished, the OK status is sent to terminate
+ // this RPC.
+ rpc RunServer(stream ServerArgs) returns (stream ServerStatus);
+
+ // Start client with specified workload.
+ // First request sent specifies the ClientConfig followed by ClientStatus
+ // response. After that, a "Mark" can be sent anytime to request the latest
+ // stats. Closing the stream will initiate shutdown of the test client
+ // and once the shutdown has finished, the OK status is sent to terminate
+ // this RPC.
+ rpc RunClient(stream ClientArgs) returns (stream ClientStatus);
+
+ // Just return the core count - unary call
+ rpc CoreCount(CoreRequest) returns (CoreResponse);
+
+ // Quit this worker
+ rpc QuitWorker(Void) returns (Void);
+}
diff --git a/src/python/grpcio/grpc/__init__.py b/src/python/grpcio/grpc/__init__.py
index 7fa7303..b7ed0c8 100644
--- a/src/python/grpcio/grpc/__init__.py
+++ b/src/python/grpcio/grpc/__init__.py
@@ -813,7 +813,11 @@
class Channel(six.with_metaclass(abc.ABCMeta)):
- """Affords RPC invocation via generic methods on client-side."""
+ """Affords RPC invocation via generic methods on client-side.
+
+ Channel objects implement the Context Manager type, although they need not
+ support being entered and exited multiple times.
+ """
@abc.abstractmethod
def subscribe(self, callback, try_to_connect=False):
@@ -926,6 +930,17 @@
"""
raise NotImplementedError()
+ @abc.abstractmethod
+ def close(self):
+ """Closes this Channel and releases all resources held by it.
+
+ Closing the Channel will immediately terminate all RPCs active with the
+ Channel and it is not valid to invoke new RPCs with the Channel.
+
+ This method is idempotent.
+ """
+ raise NotImplementedError()
+
########################## Service-Side Context ##############################
diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py
index 2eff08a..8cc0e98 100644
--- a/src/python/grpcio/grpc/_channel.py
+++ b/src/python/grpcio/grpc/_channel.py
@@ -79,27 +79,6 @@
condition.wait(timeout=remaining)
-_INTERNAL_CALL_ERROR_MESSAGE_FORMAT = (
- 'Internal gRPC call error %d. ' +
- 'Please report to https://github.com/grpc/grpc/issues')
-
-
-def _check_call_error(call_error, metadata):
- if call_error == cygrpc.CallError.invalid_metadata:
- raise ValueError('metadata was invalid: %s' % metadata)
- elif call_error != cygrpc.CallError.ok:
- raise ValueError(_INTERNAL_CALL_ERROR_MESSAGE_FORMAT % call_error)
-
-
-def _call_error_set_RPCstate(state, call_error, metadata):
- if call_error == cygrpc.CallError.invalid_metadata:
- _abort(state, grpc.StatusCode.INTERNAL,
- 'metadata was invalid: %s' % metadata)
- else:
- _abort(state, grpc.StatusCode.INTERNAL,
- _INTERNAL_CALL_ERROR_MESSAGE_FORMAT % call_error)
-
-
class _RPCState(object):
def __init__(self, due, initial_metadata, trailing_metadata, code, details):
@@ -163,7 +142,7 @@
return callbacks
-def _event_handler(state, call, response_deserializer):
+def _event_handler(state, response_deserializer):
def handle_event(event):
with state.condition:
@@ -172,40 +151,47 @@
done = not state.due
for callback in callbacks:
callback()
- return call if done else None
+ return done
return handle_event
-def _consume_request_iterator(request_iterator, state, call,
- request_serializer):
- event_handler = _event_handler(state, call, None)
+def _consume_request_iterator(request_iterator, state, call, request_serializer,
+ event_handler):
- def consume_request_iterator():
+ def consume_request_iterator(): # pylint: disable=too-many-branches
while True:
try:
request = next(request_iterator)
except StopIteration:
break
except Exception: # pylint: disable=broad-except
- logging.exception("Exception iterating requests!")
- call.cancel()
- _abort(state, grpc.StatusCode.UNKNOWN,
- "Exception iterating requests!")
+ code = grpc.StatusCode.UNKNOWN
+ details = 'Exception iterating requests!'
+ logging.exception(details)
+ call.cancel(_common.STATUS_CODE_TO_CYGRPC_STATUS_CODE[code],
+ details)
+ _abort(state, code, details)
return
serialized_request = _common.serialize(request, request_serializer)
with state.condition:
if state.code is None and not state.cancelled:
if serialized_request is None:
- call.cancel()
+ code = grpc.StatusCode.INTERNAL # pylint: disable=redefined-variable-type
details = 'Exception serializing request!'
- _abort(state, grpc.StatusCode.INTERNAL, details)
+ call.cancel(
+ _common.STATUS_CODE_TO_CYGRPC_STATUS_CODE[code],
+ details)
+ _abort(state, code, details)
return
else:
operations = (cygrpc.SendMessageOperation(
serialized_request, _EMPTY_FLAGS),)
- call.start_client_batch(operations, event_handler)
- state.due.add(cygrpc.OperationType.send_message)
+ operating = call.operate(operations, event_handler)
+ if operating:
+ state.due.add(cygrpc.OperationType.send_message)
+ else:
+ return
while True:
state.condition.wait()
if state.code is None:
@@ -219,19 +205,12 @@
if state.code is None:
operations = (
cygrpc.SendCloseFromClientOperation(_EMPTY_FLAGS),)
- call.start_client_batch(operations, event_handler)
- state.due.add(cygrpc.OperationType.send_close_from_client)
+ operating = call.operate(operations, event_handler)
+ if operating:
+ state.due.add(cygrpc.OperationType.send_close_from_client)
- def stop_consumption_thread(timeout): # pylint: disable=unused-argument
- with state.condition:
- if state.code is None:
- call.cancel()
- state.cancelled = True
- _abort(state, grpc.StatusCode.CANCELLED, 'Cancelled!')
- state.condition.notify_all()
-
- consumption_thread = _common.CleanupThread(
- stop_consumption_thread, target=consume_request_iterator)
+ consumption_thread = threading.Thread(target=consume_request_iterator)
+ consumption_thread.daemon = True
consumption_thread.start()
@@ -247,9 +226,12 @@
def cancel(self):
with self._state.condition:
if self._state.code is None:
- self._call.cancel()
+ code = grpc.StatusCode.CANCELLED
+ details = 'Locally cancelled by application!'
+ self._call.cancel(
+ _common.STATUS_CODE_TO_CYGRPC_STATUS_CODE[code], details)
self._state.cancelled = True
- _abort(self._state, grpc.StatusCode.CANCELLED, 'Cancelled!')
+ _abort(self._state, code, details)
self._state.condition.notify_all()
return False
@@ -318,12 +300,13 @@
def _next(self):
with self._state.condition:
if self._state.code is None:
- event_handler = _event_handler(self._state, self._call,
+ event_handler = _event_handler(self._state,
self._response_deserializer)
- self._call.start_client_batch(
+ operating = self._call.operate(
(cygrpc.ReceiveMessageOperation(_EMPTY_FLAGS),),
event_handler)
- self._state.due.add(cygrpc.OperationType.receive_message)
+ if operating:
+ self._state.due.add(cygrpc.OperationType.receive_message)
elif self._state.code is grpc.StatusCode.OK:
raise StopIteration()
else:
@@ -408,9 +391,12 @@
def __del__(self):
with self._state.condition:
if self._state.code is None:
- self._call.cancel()
- self._state.cancelled = True
self._state.code = grpc.StatusCode.CANCELLED
+ self._state.details = 'Cancelled upon garbage collection!'
+ self._state.cancelled = True
+ self._call.cancel(
+ _common.STATUS_CODE_TO_CYGRPC_STATUS_CODE[self._state.code],
+ self._state.details)
self._state.condition.notify_all()
@@ -437,6 +423,24 @@
raise _Rendezvous(state, None, None, deadline)
+def _stream_unary_invocation_operationses(metadata):
+ return (
+ (
+ cygrpc.SendInitialMetadataOperation(metadata, _EMPTY_FLAGS),
+ cygrpc.ReceiveMessageOperation(_EMPTY_FLAGS),
+ cygrpc.ReceiveStatusOnClientOperation(_EMPTY_FLAGS),
+ ),
+ (cygrpc.ReceiveInitialMetadataOperation(_EMPTY_FLAGS),),
+ )
+
+
+def _stream_unary_invocation_operationses_and_tags(metadata):
+ return tuple((
+ operations,
+ None,
+ ) for operations in _stream_unary_invocation_operationses(metadata))
+
+
class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable):
def __init__(self, channel, managed_call, method, request_serializer,
@@ -448,8 +452,8 @@
self._response_deserializer = response_deserializer
def _prepare(self, request, timeout, metadata):
- deadline, serialized_request, rendezvous = (_start_unary_request(
- request, timeout, self._request_serializer))
+ deadline, serialized_request, rendezvous = _start_unary_request(
+ request, timeout, self._request_serializer)
if serialized_request is None:
return None, None, None, rendezvous
else:
@@ -467,48 +471,38 @@
def _blocking(self, request, timeout, metadata, credentials):
state, operations, deadline, rendezvous = self._prepare(
request, timeout, metadata)
- if rendezvous:
+ if state is None:
raise rendezvous
else:
- completion_queue = cygrpc.CompletionQueue()
- call = self._channel.create_call(None, 0, completion_queue,
- self._method, None, deadline)
- if credentials is not None:
- call.set_credentials(credentials._credentials)
- call_error = call.start_client_batch(operations, None)
- _check_call_error(call_error, metadata)
- _handle_event(completion_queue.poll(), state,
- self._response_deserializer)
- return state, call, deadline
+ call = self._channel.segregated_call(
+ 0, self._method, None, deadline, metadata, None
+ if credentials is None else credentials._credentials, ((
+ operations,
+ None,
+ ),))
+ event = call.next_event()
+ _handle_event(event, state, self._response_deserializer)
+ return state, call,
def __call__(self, request, timeout=None, metadata=None, credentials=None):
- state, call, deadline = self._blocking(request, timeout, metadata,
- credentials)
- return _end_unary_response_blocking(state, call, False, deadline)
+ state, call, = self._blocking(request, timeout, metadata, credentials)
+ return _end_unary_response_blocking(state, call, False, None)
def with_call(self, request, timeout=None, metadata=None, credentials=None):
- state, call, deadline = self._blocking(request, timeout, metadata,
- credentials)
- return _end_unary_response_blocking(state, call, True, deadline)
+ state, call, = self._blocking(request, timeout, metadata, credentials)
+ return _end_unary_response_blocking(state, call, True, None)
def future(self, request, timeout=None, metadata=None, credentials=None):
state, operations, deadline, rendezvous = self._prepare(
request, timeout, metadata)
- if rendezvous:
- return rendezvous
+ if state is None:
+ raise rendezvous
else:
- call, drive_call = self._managed_call(None, 0, self._method, None,
- deadline)
- if credentials is not None:
- call.set_credentials(credentials._credentials)
- event_handler = _event_handler(state, call,
- self._response_deserializer)
- with state.condition:
- call_error = call.start_client_batch(operations, event_handler)
- if call_error != cygrpc.CallError.ok:
- _call_error_set_RPCstate(state, call_error, metadata)
- return _Rendezvous(state, None, None, deadline)
- drive_call()
+ event_handler = _event_handler(state, self._response_deserializer)
+ call = self._managed_call(
+ 0, self._method, None, deadline, metadata, None
+ if credentials is None else credentials._credentials,
+ (operations,), event_handler)
return _Rendezvous(state, call, self._response_deserializer,
deadline)
@@ -524,34 +518,27 @@
self._response_deserializer = response_deserializer
def __call__(self, request, timeout=None, metadata=None, credentials=None):
- deadline, serialized_request, rendezvous = (_start_unary_request(
- request, timeout, self._request_serializer))
+ deadline, serialized_request, rendezvous = _start_unary_request(
+ request, timeout, self._request_serializer)
if serialized_request is None:
raise rendezvous
else:
state = _RPCState(_UNARY_STREAM_INITIAL_DUE, None, None, None, None)
- call, drive_call = self._managed_call(None, 0, self._method, None,
- deadline)
- if credentials is not None:
- call.set_credentials(credentials._credentials)
- event_handler = _event_handler(state, call,
- self._response_deserializer)
- with state.condition:
- call.start_client_batch(
- (cygrpc.ReceiveInitialMetadataOperation(_EMPTY_FLAGS),),
- event_handler)
- operations = (
+ operationses = (
+ (
cygrpc.SendInitialMetadataOperation(metadata, _EMPTY_FLAGS),
cygrpc.SendMessageOperation(serialized_request,
_EMPTY_FLAGS),
cygrpc.SendCloseFromClientOperation(_EMPTY_FLAGS),
cygrpc.ReceiveStatusOnClientOperation(_EMPTY_FLAGS),
- )
- call_error = call.start_client_batch(operations, event_handler)
- if call_error != cygrpc.CallError.ok:
- _call_error_set_RPCstate(state, call_error, metadata)
- return _Rendezvous(state, None, None, deadline)
- drive_call()
+ ),
+ (cygrpc.ReceiveInitialMetadataOperation(_EMPTY_FLAGS),),
+ )
+ event_handler = _event_handler(state, self._response_deserializer)
+ call = self._managed_call(
+ 0, self._method, None, deadline, metadata, None
+ if credentials is None else credentials._credentials,
+ operationses, event_handler)
return _Rendezvous(state, call, self._response_deserializer,
deadline)
@@ -569,49 +556,38 @@
def _blocking(self, request_iterator, timeout, metadata, credentials):
deadline = _deadline(timeout)
state = _RPCState(_STREAM_UNARY_INITIAL_DUE, None, None, None, None)
- completion_queue = cygrpc.CompletionQueue()
- call = self._channel.create_call(None, 0, completion_queue,
- self._method, None, deadline)
- if credentials is not None:
- call.set_credentials(credentials._credentials)
- with state.condition:
- call.start_client_batch(
- (cygrpc.ReceiveInitialMetadataOperation(_EMPTY_FLAGS),), None)
- operations = (
- cygrpc.SendInitialMetadataOperation(metadata, _EMPTY_FLAGS),
- cygrpc.ReceiveMessageOperation(_EMPTY_FLAGS),
- cygrpc.ReceiveStatusOnClientOperation(_EMPTY_FLAGS),
- )
- call_error = call.start_client_batch(operations, None)
- _check_call_error(call_error, metadata)
- _consume_request_iterator(request_iterator, state, call,
- self._request_serializer)
+ call = self._channel.segregated_call(
+ 0, self._method, None, deadline, metadata, None
+ if credentials is None else credentials._credentials,
+ _stream_unary_invocation_operationses_and_tags(metadata))
+ _consume_request_iterator(request_iterator, state, call,
+ self._request_serializer, None)
while True:
- event = completion_queue.poll()
+ event = call.next_event()
with state.condition:
_handle_event(event, state, self._response_deserializer)
state.condition.notify_all()
if not state.due:
break
- return state, call, deadline
+ return state, call,
def __call__(self,
request_iterator,
timeout=None,
metadata=None,
credentials=None):
- state, call, deadline = self._blocking(request_iterator, timeout,
- metadata, credentials)
- return _end_unary_response_blocking(state, call, False, deadline)
+ state, call, = self._blocking(request_iterator, timeout, metadata,
+ credentials)
+ return _end_unary_response_blocking(state, call, False, None)
def with_call(self,
request_iterator,
timeout=None,
metadata=None,
credentials=None):
- state, call, deadline = self._blocking(request_iterator, timeout,
- metadata, credentials)
- return _end_unary_response_blocking(state, call, True, deadline)
+ state, call, = self._blocking(request_iterator, timeout, metadata,
+ credentials)
+ return _end_unary_response_blocking(state, call, True, None)
def future(self,
request_iterator,
@@ -620,27 +596,13 @@
credentials=None):
deadline = _deadline(timeout)
state = _RPCState(_STREAM_UNARY_INITIAL_DUE, None, None, None, None)
- call, drive_call = self._managed_call(None, 0, self._method, None,
- deadline)
- if credentials is not None:
- call.set_credentials(credentials._credentials)
- event_handler = _event_handler(state, call, self._response_deserializer)
- with state.condition:
- call.start_client_batch(
- (cygrpc.ReceiveInitialMetadataOperation(_EMPTY_FLAGS),),
- event_handler)
- operations = (
- cygrpc.SendInitialMetadataOperation(metadata, _EMPTY_FLAGS),
- cygrpc.ReceiveMessageOperation(_EMPTY_FLAGS),
- cygrpc.ReceiveStatusOnClientOperation(_EMPTY_FLAGS),
- )
- call_error = call.start_client_batch(operations, event_handler)
- if call_error != cygrpc.CallError.ok:
- _call_error_set_RPCstate(state, call_error, metadata)
- return _Rendezvous(state, None, None, deadline)
- drive_call()
- _consume_request_iterator(request_iterator, state, call,
- self._request_serializer)
+ event_handler = _event_handler(state, self._response_deserializer)
+ call = self._managed_call(
+ 0, self._method, None, deadline, metadata, None
+ if credentials is None else credentials._credentials,
+ _stream_unary_invocation_operationses(metadata), event_handler)
+ _consume_request_iterator(request_iterator, state, call,
+ self._request_serializer, event_handler)
return _Rendezvous(state, call, self._response_deserializer, deadline)
@@ -661,26 +623,20 @@
credentials=None):
deadline = _deadline(timeout)
state = _RPCState(_STREAM_STREAM_INITIAL_DUE, None, None, None, None)
- call, drive_call = self._managed_call(None, 0, self._method, None,
- deadline)
- if credentials is not None:
- call.set_credentials(credentials._credentials)
- event_handler = _event_handler(state, call, self._response_deserializer)
- with state.condition:
- call.start_client_batch(
- (cygrpc.ReceiveInitialMetadataOperation(_EMPTY_FLAGS),),
- event_handler)
- operations = (
+ operationses = (
+ (
cygrpc.SendInitialMetadataOperation(metadata, _EMPTY_FLAGS),
cygrpc.ReceiveStatusOnClientOperation(_EMPTY_FLAGS),
- )
- call_error = call.start_client_batch(operations, event_handler)
- if call_error != cygrpc.CallError.ok:
- _call_error_set_RPCstate(state, call_error, metadata)
- return _Rendezvous(state, None, None, deadline)
- drive_call()
- _consume_request_iterator(request_iterator, state, call,
- self._request_serializer)
+ ),
+ (cygrpc.ReceiveInitialMetadataOperation(_EMPTY_FLAGS),),
+ )
+ event_handler = _event_handler(state, self._response_deserializer)
+ call = self._managed_call(
+ 0, self._method, None, deadline, metadata, None
+ if credentials is None else credentials._credentials, operationses,
+ event_handler)
+ _consume_request_iterator(request_iterator, state, call,
+ self._request_serializer, event_handler)
return _Rendezvous(state, call, self._response_deserializer, deadline)
@@ -689,67 +645,63 @@
def __init__(self, channel):
self.lock = threading.Lock()
self.channel = channel
- self.completion_queue = cygrpc.CompletionQueue()
- self.managed_calls = None
+ self.managed_calls = 0
def _run_channel_spin_thread(state):
def channel_spin():
while True:
- event = state.completion_queue.poll()
- completed_call = event.tag(event)
- if completed_call is not None:
+ event = state.channel.next_call_event()
+ call_completed = event.tag(event)
+ if call_completed:
with state.lock:
- state.managed_calls.remove(completed_call)
- if not state.managed_calls:
- state.managed_calls = None
+ state.managed_calls -= 1
+ if state.managed_calls == 0:
return
- def stop_channel_spin(timeout): # pylint: disable=unused-argument
- with state.lock:
- if state.managed_calls is not None:
- for call in state.managed_calls:
- call.cancel()
-
- channel_spin_thread = _common.CleanupThread(
- stop_channel_spin, target=channel_spin)
+ channel_spin_thread = threading.Thread(target=channel_spin)
+ channel_spin_thread.daemon = True
channel_spin_thread.start()
def _channel_managed_call_management(state):
- def create(parent, flags, method, host, deadline):
- """Creates a managed cygrpc.Call and a function to call to drive it.
+ # pylint: disable=too-many-arguments
+ def create(flags, method, host, deadline, metadata, credentials,
+ operationses, event_handler):
+ """Creates a cygrpc.IntegratedCall.
- If operations are successfully added to the returned cygrpc.Call, the
- returned function must be called. If operations are not successfully added
- to the returned cygrpc.Call, the returned function must not be called.
+ Args:
+ flags: An integer bitfield of call flags.
+ method: The RPC method.
+ host: A host string for the created call.
+ deadline: A float to be the deadline of the created call or None if
+ the call is to have an infinite deadline.
+ metadata: The metadata for the call or None.
+ credentials: A cygrpc.CallCredentials or None.
+ operationses: An iterable of iterables of cygrpc.Operations to be
+ started on the call.
+ event_handler: A behavior to call to handle the events resultant from
+ the operations on the call.
- Args:
- parent: A cygrpc.Call to be used as the parent of the created call.
- flags: An integer bitfield of call flags.
- method: The RPC method.
- host: A host string for the created call.
- deadline: A float to be the deadline of the created call or None if the
- call is to have an infinite deadline.
-
- Returns:
- A cygrpc.Call with which to conduct an RPC and a function to call if
- operations are successfully started on the call.
- """
- call = state.channel.create_call(parent, flags, state.completion_queue,
- method, host, deadline)
-
- def drive():
- with state.lock:
- if state.managed_calls is None:
- state.managed_calls = set((call,))
- _run_channel_spin_thread(state)
- else:
- state.managed_calls.add(call)
-
- return call, drive
+ Returns:
+ A cygrpc.IntegratedCall with which to conduct an RPC.
+ """
+ operationses_and_tags = tuple((
+ operations,
+ event_handler,
+ ) for operations in operationses)
+ with state.lock:
+ call = state.channel.integrated_call(flags, method, host, deadline,
+ metadata, credentials,
+ operationses_and_tags)
+ if state.managed_calls == 0:
+ state.managed_calls = 1
+ _run_channel_spin_thread(state)
+ else:
+ state.managed_calls += 1
+ return call
return create
@@ -819,12 +771,9 @@
callback_and_connectivity[1] = state.connectivity
if callbacks:
_spawn_delivery(state, callbacks)
- completion_queue = cygrpc.CompletionQueue()
while True:
- channel.watch_connectivity_state(connectivity,
- time.time() + 0.2, completion_queue,
- None)
- event = completion_queue.poll()
+ event = channel.watch_connectivity_state(connectivity,
+ time.time() + 0.2)
with state.lock:
if not state.callbacks_and_connectivities and not state.try_to_connect:
state.polling = False
@@ -855,10 +804,10 @@
def _subscribe(state, callback, try_to_connect):
with state.lock:
if not state.callbacks_and_connectivities and not state.polling:
- polling_thread = _common.CleanupThread(
- lambda timeout: _moot(state),
+ polling_thread = threading.Thread(
target=_poll_connectivity,
args=(state, state.channel, bool(try_to_connect)))
+ polling_thread.daemon = True
polling_thread.start()
state.polling = True
state.callbacks_and_connectivities.append([callback, None])
@@ -944,5 +893,28 @@
self._channel, _channel_managed_call_management(self._call_state),
_common.encode(method), request_serializer, response_deserializer)
+ def _close(self):
+ self._channel.close(cygrpc.StatusCode.cancelled, 'Channel closed!')
+ _moot(self._connectivity_state)
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, exc_type, exc_val, exc_tb):
+ self._close()
+ return False
+
+ def close(self):
+ self._close()
+
def __del__(self):
+ # TODO(https://github.com/grpc/grpc/issues/12531): Several releases
+ # after 1.12 (1.16 or thereabouts?) add a "self._channel.close" call
+ # here (or more likely, call self._close() here). We don't do this today
+ # because many valid use cases today allow the channel to be deleted
+ # immediately after stubs are created. After a sufficient period of time
+ # has passed for all users to be trusted to hang out to their channels
+ # for as long as they are in use and to close them after using them,
+ # then deletion of this grpc._channel.Channel instance can be made to
+ # effect closure of the underlying cygrpc.Channel instance.
_moot(self._connectivity_state)
diff --git a/src/python/grpcio/grpc/_common.py b/src/python/grpcio/grpc/_common.py
index bbb69ad..862987a 100644
--- a/src/python/grpcio/grpc/_common.py
+++ b/src/python/grpcio/grpc/_common.py
@@ -14,8 +14,6 @@
"""Shared implementation."""
import logging
-import threading
-import time
import six
@@ -101,35 +99,3 @@
def fully_qualified_method(group, method):
return '/{}/{}'.format(group, method)
-
-
-class CleanupThread(threading.Thread):
- """A threading.Thread subclass supporting custom behavior on join().
-
- On Python Interpreter exit, Python will attempt to join outstanding threads
- prior to garbage collection. We may need to do additional cleanup, and
- we accomplish this by overriding the join() method.
- """
-
- def __init__(self, behavior, *args, **kwargs):
- """Constructor.
-
- Args:
- behavior (function): Function called on join() with a single
- argument, timeout, indicating the maximum duration of
- `behavior`, or None indicating `behavior` has no deadline.
- `behavior` must be idempotent.
- args: Positional arguments passed to threading.Thread constructor.
- kwargs: Keyword arguments passed to threading.Thread constructor.
- """
- super(CleanupThread, self).__init__(*args, **kwargs)
- self._behavior = behavior
-
- def join(self, timeout=None):
- start_time = time.time()
- self._behavior(timeout)
- end_time = time.time()
- if timeout is not None:
- timeout -= end_time - start_time
- timeout = max(timeout, 0)
- super(CleanupThread, self).join(timeout)
diff --git a/src/python/grpcio/grpc/_cython/.gitignore b/src/python/grpcio/grpc/_cython/.gitignore
index 306e3ad..b9936e9 100644
--- a/src/python/grpcio/grpc/_cython/.gitignore
+++ b/src/python/grpcio/grpc/_cython/.gitignore
@@ -1,4 +1,4 @@
-cygrpc.c
+cygrpc.cpp
*.a
*.so
*.dll
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pxd.pxi
index 1ba76b7..eefc685 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pxd.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pxd.pxi
@@ -13,9 +13,59 @@
# limitations under the License.
+cdef _check_call_error_no_metadata(c_call_error)
+
+
+cdef _check_and_raise_call_error_no_metadata(c_call_error)
+
+
+cdef _check_call_error(c_call_error, metadata)
+
+
+cdef class _CallState:
+
+ cdef grpc_call *c_call
+ cdef set due
+
+
+cdef class _ChannelState:
+
+ cdef object condition
+ cdef grpc_channel *c_channel
+ # A boolean field indicating that the channel is open (if True) or is being
+ # closed (i.e. a call to close is currently executing) or is closed (if
+ # False).
+ # TODO(https://github.com/grpc/grpc/issues/3064): Eliminate "is being closed"
+ # a state in which condition may be acquired by any thread, eliminate this
+ # field and just use the NULLness of c_channel as an indication that the
+ # channel is closed.
+ cdef object open
+
+ # A dict from _BatchOperationTag to _CallState
+ cdef dict integrated_call_states
+ cdef grpc_completion_queue *c_call_completion_queue
+
+ # A set of _CallState
+ cdef set segregated_call_states
+
+ cdef set connectivity_due
+ cdef grpc_completion_queue *c_connectivity_completion_queue
+
+
+cdef class IntegratedCall:
+
+ cdef _ChannelState _channel_state
+ cdef _CallState _call_state
+
+
+cdef class SegregatedCall:
+
+ cdef _ChannelState _channel_state
+ cdef _CallState _call_state
+ cdef grpc_completion_queue *_c_completion_queue
+
+
cdef class Channel:
cdef grpc_arg_pointer_vtable _vtable
- cdef grpc_channel *c_channel
- cdef list references
- cdef readonly _ArgumentsProcessor _arguments_processor
+ cdef _ChannelState _state
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi
index a396649..72e74e8 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi
@@ -14,82 +14,439 @@
cimport cpython
+import threading
+
+_INTERNAL_CALL_ERROR_MESSAGE_FORMAT = (
+ 'Internal gRPC call error %d. ' +
+ 'Please report to https://github.com/grpc/grpc/issues')
+
+
+cdef str _call_error_metadata(metadata):
+ return 'metadata was invalid: %s' % metadata
+
+
+cdef str _call_error_no_metadata(c_call_error):
+ return _INTERNAL_CALL_ERROR_MESSAGE_FORMAT % c_call_error
+
+
+cdef str _call_error(c_call_error, metadata):
+ if c_call_error == GRPC_CALL_ERROR_INVALID_METADATA:
+ return _call_error_metadata(metadata)
+ else:
+ return _call_error_no_metadata(c_call_error)
+
+
+cdef _check_call_error_no_metadata(c_call_error):
+ if c_call_error != GRPC_CALL_OK:
+ return _INTERNAL_CALL_ERROR_MESSAGE_FORMAT % c_call_error
+ else:
+ return None
+
+
+cdef _check_and_raise_call_error_no_metadata(c_call_error):
+ error = _check_call_error_no_metadata(c_call_error)
+ if error is not None:
+ raise ValueError(error)
+
+
+cdef _check_call_error(c_call_error, metadata):
+ if c_call_error == GRPC_CALL_ERROR_INVALID_METADATA:
+ return _call_error_metadata(metadata)
+ else:
+ return _check_call_error_no_metadata(c_call_error)
+
+
+cdef void _raise_call_error_no_metadata(c_call_error) except *:
+ raise ValueError(_call_error_no_metadata(c_call_error))
+
+
+cdef void _raise_call_error(c_call_error, metadata) except *:
+ raise ValueError(_call_error(c_call_error, metadata))
+
+
+cdef _destroy_c_completion_queue(grpc_completion_queue *c_completion_queue):
+ grpc_completion_queue_shutdown(c_completion_queue)
+ grpc_completion_queue_destroy(c_completion_queue)
+
+
+cdef class _CallState:
+
+ def __cinit__(self):
+ self.due = set()
+
+
+cdef class _ChannelState:
+
+ def __cinit__(self):
+ self.condition = threading.Condition()
+ self.open = True
+ self.integrated_call_states = {}
+ self.segregated_call_states = set()
+ self.connectivity_due = set()
+
+
+cdef tuple _operate(grpc_call *c_call, object operations, object user_tag):
+ cdef grpc_call_error c_call_error
+ cdef _BatchOperationTag tag = _BatchOperationTag(user_tag, operations, None)
+ tag.prepare()
+ cpython.Py_INCREF(tag)
+ with nogil:
+ c_call_error = grpc_call_start_batch(
+ c_call, tag.c_ops, tag.c_nops, <cpython.PyObject *>tag, NULL)
+ return c_call_error, tag
+
+
+cdef object _operate_from_integrated_call(
+ _ChannelState channel_state, _CallState call_state, object operations,
+ object user_tag):
+ cdef grpc_call_error c_call_error
+ cdef _BatchOperationTag tag
+ with channel_state.condition:
+ if call_state.due:
+ c_call_error, tag = _operate(call_state.c_call, operations, user_tag)
+ if c_call_error == GRPC_CALL_OK:
+ call_state.due.add(tag)
+ channel_state.integrated_call_states[tag] = call_state
+ return True
+ else:
+ _raise_call_error_no_metadata(c_call_error)
+ else:
+ return False
+
+
+cdef object _operate_from_segregated_call(
+ _ChannelState channel_state, _CallState call_state, object operations,
+ object user_tag):
+ cdef grpc_call_error c_call_error
+ cdef _BatchOperationTag tag
+ with channel_state.condition:
+ if call_state.due:
+ c_call_error, tag = _operate(call_state.c_call, operations, user_tag)
+ if c_call_error == GRPC_CALL_OK:
+ call_state.due.add(tag)
+ return True
+ else:
+ _raise_call_error_no_metadata(c_call_error)
+ else:
+ return False
+
+
+cdef _cancel(
+ _ChannelState channel_state, _CallState call_state, grpc_status_code code,
+ str details):
+ cdef grpc_call_error c_call_error
+ with channel_state.condition:
+ if call_state.due:
+ c_call_error = grpc_call_cancel_with_status(
+ call_state.c_call, code, _encode(details), NULL)
+ _check_and_raise_call_error_no_metadata(c_call_error)
+
+
+cdef BatchOperationEvent _next_call_event(
+ _ChannelState channel_state, grpc_completion_queue *c_completion_queue,
+ on_success):
+ tag, event = _latent_event(c_completion_queue, None)
+ with channel_state.condition:
+ on_success(tag)
+ channel_state.condition.notify_all()
+ return event
+
+
+# TODO(https://github.com/grpc/grpc/issues/14569): This could be a lot simpler.
+cdef void _call(
+ _ChannelState channel_state, _CallState call_state,
+ grpc_completion_queue *c_completion_queue, on_success, int flags, method,
+ host, object deadline, CallCredentials credentials,
+ object operationses_and_user_tags, object metadata) except *:
+ """Invokes an RPC.
+
+ Args:
+ channel_state: A _ChannelState with its "open" attribute set to True. RPCs
+ may not be invoked on a closed channel.
+ call_state: An empty _CallState to be altered (specifically assigned a
+ c_call and having its due set populated) if the RPC invocation is
+ successful.
+ c_completion_queue: A grpc_completion_queue to be used for the call's
+ operations.
+ on_success: A behavior to be called if attempting to start operations for
+ the call succeeds. If called the behavior will be called while holding the
+ channel_state condition and passed the tags associated with operations
+ that were successfully started for the call.
+ flags: Flags to be passed to gRPC Core as part of call creation.
+ method: The fully-qualified name of the RPC method being invoked.
+ host: A "host" string to be passed to gRPC Core as part of call creation.
+ deadline: A float for the deadline of the RPC, or None if the RPC is to have
+ no deadline.
+ credentials: A _CallCredentials for the RPC or None.
+ operationses_and_user_tags: A sequence of length-two sequences the first
+ element of which is a sequence of Operations and the second element of
+ which is an object to be used as a tag. A SendInitialMetadataOperation
+ must be present in the first element of this value.
+ metadata: The metadata for this call.
+ """
+ cdef grpc_slice method_slice
+ cdef grpc_slice host_slice
+ cdef grpc_slice *host_slice_ptr
+ cdef grpc_call_credentials *c_call_credentials
+ cdef grpc_call_error c_call_error
+ cdef tuple error_and_wrapper_tag
+ cdef _BatchOperationTag wrapper_tag
+ with channel_state.condition:
+ if channel_state.open:
+ method_slice = _slice_from_bytes(method)
+ if host is None:
+ host_slice_ptr = NULL
+ else:
+ host_slice = _slice_from_bytes(host)
+ host_slice_ptr = &host_slice
+ call_state.c_call = grpc_channel_create_call(
+ channel_state.c_channel, NULL, flags,
+ c_completion_queue, method_slice, host_slice_ptr,
+ _timespec_from_time(deadline), NULL)
+ grpc_slice_unref(method_slice)
+ if host_slice_ptr:
+ grpc_slice_unref(host_slice)
+ if credentials is not None:
+ c_call_credentials = credentials.c()
+ c_call_error = grpc_call_set_credentials(
+ call_state.c_call, c_call_credentials)
+ grpc_call_credentials_release(c_call_credentials)
+ if c_call_error != GRPC_CALL_OK:
+ grpc_call_unref(call_state.c_call)
+ call_state.c_call = NULL
+ _raise_call_error_no_metadata(c_call_error)
+ started_tags = set()
+ for operations, user_tag in operationses_and_user_tags:
+ c_call_error, tag = _operate(call_state.c_call, operations, user_tag)
+ if c_call_error == GRPC_CALL_OK:
+ started_tags.add(tag)
+ else:
+ grpc_call_cancel(call_state.c_call, NULL)
+ grpc_call_unref(call_state.c_call)
+ call_state.c_call = NULL
+ _raise_call_error(c_call_error, metadata)
+ else:
+ call_state.due.update(started_tags)
+ on_success(started_tags)
+ else:
+ raise ValueError('Cannot invoke RPC on closed channel!')
+
+cdef void _process_integrated_call_tag(
+ _ChannelState state, _BatchOperationTag tag) except *:
+ cdef _CallState call_state = state.integrated_call_states.pop(tag)
+ call_state.due.remove(tag)
+ if not call_state.due:
+ grpc_call_unref(call_state.c_call)
+ call_state.c_call = NULL
+
+
+cdef class IntegratedCall:
+
+ def __cinit__(self, _ChannelState channel_state, _CallState call_state):
+ self._channel_state = channel_state
+ self._call_state = call_state
+
+ def operate(self, operations, tag):
+ return _operate_from_integrated_call(
+ self._channel_state, self._call_state, operations, tag)
+
+ def cancel(self, code, details):
+ _cancel(self._channel_state, self._call_state, code, details)
+
+
+cdef IntegratedCall _integrated_call(
+ _ChannelState state, int flags, method, host, object deadline,
+ object metadata, CallCredentials credentials, operationses_and_user_tags):
+ call_state = _CallState()
+
+ def on_success(started_tags):
+ for started_tag in started_tags:
+ state.integrated_call_states[started_tag] = call_state
+
+ _call(
+ state, call_state, state.c_call_completion_queue, on_success, flags,
+ method, host, deadline, credentials, operationses_and_user_tags, metadata)
+
+ return IntegratedCall(state, call_state)
+
+
+cdef object _process_segregated_call_tag(
+ _ChannelState state, _CallState call_state,
+ grpc_completion_queue *c_completion_queue, _BatchOperationTag tag):
+ call_state.due.remove(tag)
+ if not call_state.due:
+ grpc_call_unref(call_state.c_call)
+ call_state.c_call = NULL
+ state.segregated_call_states.remove(call_state)
+ _destroy_c_completion_queue(c_completion_queue)
+ return True
+ else:
+ return False
+
+
+cdef class SegregatedCall:
+
+ def __cinit__(self, _ChannelState channel_state, _CallState call_state):
+ self._channel_state = channel_state
+ self._call_state = call_state
+
+ def operate(self, operations, tag):
+ return _operate_from_segregated_call(
+ self._channel_state, self._call_state, operations, tag)
+
+ def cancel(self, code, details):
+ _cancel(self._channel_state, self._call_state, code, details)
+
+ def next_event(self):
+ def on_success(tag):
+ _process_segregated_call_tag(
+ self._channel_state, self._call_state, self._c_completion_queue, tag)
+ return _next_call_event(
+ self._channel_state, self._c_completion_queue, on_success)
+
+
+cdef SegregatedCall _segregated_call(
+ _ChannelState state, int flags, method, host, object deadline,
+ object metadata, CallCredentials credentials, operationses_and_user_tags):
+ cdef _CallState call_state = _CallState()
+ cdef grpc_completion_queue *c_completion_queue = (
+ grpc_completion_queue_create_for_next(NULL))
+ cdef SegregatedCall segregated_call
+
+ def on_success(started_tags):
+ state.segregated_call_states.add(call_state)
+
+ try:
+ _call(
+ state, call_state, c_completion_queue, on_success, flags, method, host,
+ deadline, credentials, operationses_and_user_tags, metadata)
+ except:
+ _destroy_c_completion_queue(c_completion_queue)
+ raise
+
+ segregated_call = SegregatedCall(state, call_state)
+ segregated_call._c_completion_queue = c_completion_queue
+ return segregated_call
+
+
+cdef object _watch_connectivity_state(
+ _ChannelState state, grpc_connectivity_state last_observed_state,
+ object deadline):
+ cdef _ConnectivityTag tag = _ConnectivityTag(object())
+ with state.condition:
+ if state.open:
+ cpython.Py_INCREF(tag)
+ grpc_channel_watch_connectivity_state(
+ state.c_channel, last_observed_state, _timespec_from_time(deadline),
+ state.c_connectivity_completion_queue, <cpython.PyObject *>tag)
+ state.connectivity_due.add(tag)
+ else:
+ raise ValueError('Cannot invoke RPC on closed channel!')
+ completed_tag, event = _latent_event(
+ state.c_connectivity_completion_queue, None)
+ with state.condition:
+ state.connectivity_due.remove(completed_tag)
+ state.condition.notify_all()
+ return event
+
+
+cdef _close(_ChannelState state, grpc_status_code code, object details):
+ cdef _CallState call_state
+ encoded_details = _encode(details)
+ with state.condition:
+ if state.open:
+ state.open = False
+ for call_state in set(state.integrated_call_states.values()):
+ grpc_call_cancel_with_status(
+ call_state.c_call, code, encoded_details, NULL)
+ for call_state in state.segregated_call_states:
+ grpc_call_cancel_with_status(
+ call_state.c_call, code, encoded_details, NULL)
+ # TODO(https://github.com/grpc/grpc/issues/3064): Cancel connectivity
+ # watching.
+
+ while state.integrated_call_states:
+ state.condition.wait()
+ while state.segregated_call_states:
+ state.condition.wait()
+ while state.connectivity_due:
+ state.condition.wait()
+
+ _destroy_c_completion_queue(state.c_call_completion_queue)
+ _destroy_c_completion_queue(state.c_connectivity_completion_queue)
+ grpc_channel_destroy(state.c_channel)
+ state.c_channel = NULL
+ grpc_shutdown()
+ state.condition.notify_all()
+ else:
+ # Another call to close already completed in the past or is currently
+ # being executed in another thread.
+ while state.c_channel != NULL:
+ state.condition.wait()
+
cdef class Channel:
- def __cinit__(self, bytes target, object arguments,
- ChannelCredentials channel_credentials=None):
+ def __cinit__(
+ self, bytes target, object arguments,
+ ChannelCredentials channel_credentials):
grpc_init()
+ self._state = _ChannelState()
self._vtable.copy = &_copy_pointer
self._vtable.destroy = &_destroy_pointer
self._vtable.cmp = &_compare_pointer
cdef _ArgumentsProcessor arguments_processor = _ArgumentsProcessor(
arguments)
cdef grpc_channel_args *c_arguments = arguments_processor.c(&self._vtable)
- self.references = []
- c_target = target
if channel_credentials is None:
- self.c_channel = grpc_insecure_channel_create(c_target, c_arguments, NULL)
+ self._state.c_channel = grpc_insecure_channel_create(
+ <char *>target, c_arguments, NULL)
else:
c_channel_credentials = channel_credentials.c()
- self.c_channel = grpc_secure_channel_create(
- c_channel_credentials, c_target, c_arguments, NULL)
+ self._state.c_channel = grpc_secure_channel_create(
+ c_channel_credentials, <char *>target, c_arguments, NULL)
grpc_channel_credentials_release(c_channel_credentials)
- arguments_processor.un_c()
- self.references.append(target)
- self.references.append(arguments)
-
- def create_call(self, Call parent, int flags,
- CompletionQueue queue not None,
- method, host, object deadline):
- if queue.is_shutting_down:
- raise ValueError("queue must not be shutting down or shutdown")
- cdef grpc_slice method_slice = _slice_from_bytes(method)
- cdef grpc_slice host_slice
- cdef grpc_slice *host_slice_ptr = NULL
- if host is not None:
- host_slice = _slice_from_bytes(host)
- host_slice_ptr = &host_slice
- cdef Call operation_call = Call()
- operation_call.references = [self, queue]
- cdef grpc_call *parent_call = NULL
- if parent is not None:
- parent_call = parent.c_call
- operation_call.c_call = grpc_channel_create_call(
- self.c_channel, parent_call, flags,
- queue.c_completion_queue, method_slice, host_slice_ptr,
- _timespec_from_time(deadline), NULL)
- grpc_slice_unref(method_slice)
- if host_slice_ptr:
- grpc_slice_unref(host_slice)
- return operation_call
-
- def check_connectivity_state(self, bint try_to_connect):
- cdef grpc_connectivity_state result
- with nogil:
- result = grpc_channel_check_connectivity_state(self.c_channel,
- try_to_connect)
- return result
-
- def watch_connectivity_state(
- self, grpc_connectivity_state last_observed_state,
- object deadline, CompletionQueue queue not None, tag):
- cdef _ConnectivityTag connectivity_tag = _ConnectivityTag(tag)
- cpython.Py_INCREF(connectivity_tag)
- grpc_channel_watch_connectivity_state(
- self.c_channel, last_observed_state, _timespec_from_time(deadline),
- queue.c_completion_queue, <cpython.PyObject *>connectivity_tag)
+ self._state.c_call_completion_queue = (
+ grpc_completion_queue_create_for_next(NULL))
+ self._state.c_connectivity_completion_queue = (
+ grpc_completion_queue_create_for_next(NULL))
def target(self):
- cdef char *target = NULL
- with nogil:
- target = grpc_channel_get_target(self.c_channel)
- result = <bytes>target
- with nogil:
- gpr_free(target)
- return result
+ cdef char *c_target
+ with self._state.condition:
+ c_target = grpc_channel_get_target(self._state.c_channel)
+ target = <bytes>c_target
+ gpr_free(c_target)
+ return target
- def __dealloc__(self):
- if self.c_channel != NULL:
- grpc_channel_destroy(self.c_channel)
- grpc_shutdown()
+ def integrated_call(
+ self, int flags, method, host, object deadline, object metadata,
+ CallCredentials credentials, operationses_and_tags):
+ return _integrated_call(
+ self._state, flags, method, host, deadline, metadata, credentials,
+ operationses_and_tags)
+
+ def next_call_event(self):
+ def on_success(tag):
+ _process_integrated_call_tag(self._state, tag)
+ return _next_call_event(
+ self._state, self._state.c_call_completion_queue, on_success)
+
+ def segregated_call(
+ self, int flags, method, host, object deadline, object metadata,
+ CallCredentials credentials, operationses_and_tags):
+ return _segregated_call(
+ self._state, flags, method, host, deadline, metadata, credentials,
+ operationses_and_tags)
+
+ def check_connectivity_state(self, bint try_to_connect):
+ with self._state.condition:
+ return grpc_channel_check_connectivity_state(
+ self._state.c_channel, try_to_connect)
+
+ def watch_connectivity_state(
+ self, grpc_connectivity_state last_observed_state, object deadline):
+ return _watch_connectivity_state(self._state, last_observed_state, deadline)
+
+ def close(self, code, details):
+ _close(self._state, code, details)
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pxd.pxi
index 5ea0287..9f06ce0 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pxd.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pxd.pxi
@@ -13,10 +13,16 @@
# limitations under the License.
+cdef grpc_event _next(grpc_completion_queue *c_completion_queue, deadline)
+
+
+cdef _interpret_event(grpc_event c_event)
+
+
cdef class CompletionQueue:
cdef grpc_completion_queue *c_completion_queue
cdef bint is_shutting_down
cdef bint is_shutdown
- cdef _interpret_event(self, grpc_event event)
+ cdef _interpret_event(self, grpc_event c_event)
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi
index 40496d1..a2d7655 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi
@@ -20,6 +20,53 @@
cdef int _INTERRUPT_CHECK_PERIOD_MS = 200
+cdef grpc_event _next(grpc_completion_queue *c_completion_queue, deadline):
+ cdef gpr_timespec c_increment
+ cdef gpr_timespec c_timeout
+ cdef gpr_timespec c_deadline
+ c_increment = gpr_time_from_millis(_INTERRUPT_CHECK_PERIOD_MS, GPR_TIMESPAN)
+ if deadline is None:
+ c_deadline = gpr_inf_future(GPR_CLOCK_REALTIME)
+ else:
+ c_deadline = _timespec_from_time(deadline)
+
+ with nogil:
+ while True:
+ c_timeout = gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), c_increment)
+ if gpr_time_cmp(c_timeout, c_deadline) > 0:
+ c_timeout = c_deadline
+ c_event = grpc_completion_queue_next(c_completion_queue, c_timeout, NULL)
+ if (c_event.type != GRPC_QUEUE_TIMEOUT or
+ gpr_time_cmp(c_timeout, c_deadline) == 0):
+ break
+
+ # Handle any signals
+ with gil:
+ cpython.PyErr_CheckSignals()
+ return c_event
+
+
+cdef _interpret_event(grpc_event c_event):
+ cdef _Tag tag
+ if c_event.type == GRPC_QUEUE_TIMEOUT:
+ # NOTE(nathaniel): For now we coopt ConnectivityEvent here.
+ return None, ConnectivityEvent(GRPC_QUEUE_TIMEOUT, False, None)
+ elif c_event.type == GRPC_QUEUE_SHUTDOWN:
+ # NOTE(nathaniel): For now we coopt ConnectivityEvent here.
+ return None, ConnectivityEvent(GRPC_QUEUE_SHUTDOWN, False, None)
+ else:
+ tag = <_Tag>c_event.tag
+ # We receive event tags only after they've been inc-ref'd elsewhere in
+ # the code.
+ cpython.Py_DECREF(tag)
+ return tag, tag.event(c_event)
+
+
+cdef _latent_event(grpc_completion_queue *c_completion_queue, object deadline):
+ cdef grpc_event c_event = _next(c_completion_queue, deadline)
+ return _interpret_event(c_event)
+
+
cdef class CompletionQueue:
def __cinit__(self, shutdown_cq=False):
@@ -36,48 +83,16 @@
self.is_shutting_down = False
self.is_shutdown = False
- cdef _interpret_event(self, grpc_event event):
- cdef _Tag tag = None
- if event.type == GRPC_QUEUE_TIMEOUT:
- # NOTE(nathaniel): For now we coopt ConnectivityEvent here.
- return ConnectivityEvent(GRPC_QUEUE_TIMEOUT, False, None)
- elif event.type == GRPC_QUEUE_SHUTDOWN:
+ cdef _interpret_event(self, grpc_event c_event):
+ unused_tag, event = _interpret_event(c_event)
+ if event.completion_type == GRPC_QUEUE_SHUTDOWN:
self.is_shutdown = True
- # NOTE(nathaniel): For now we coopt ConnectivityEvent here.
- return ConnectivityEvent(GRPC_QUEUE_TIMEOUT, True, None)
- else:
- tag = <_Tag>event.tag
- # We receive event tags only after they've been inc-ref'd elsewhere in
- # the code.
- cpython.Py_DECREF(tag)
- return tag.event(event)
+ return event
+ # We name this 'poll' to avoid problems with CPython's expectations for
+ # 'special' methods (like next and __next__).
def poll(self, deadline=None):
- # We name this 'poll' to avoid problems with CPython's expectations for
- # 'special' methods (like next and __next__).
- cdef gpr_timespec c_increment
- cdef gpr_timespec c_timeout
- cdef gpr_timespec c_deadline
- if deadline is None:
- c_deadline = gpr_inf_future(GPR_CLOCK_REALTIME)
- else:
- c_deadline = _timespec_from_time(deadline)
- with nogil:
- c_increment = gpr_time_from_millis(_INTERRUPT_CHECK_PERIOD_MS, GPR_TIMESPAN)
-
- while True:
- c_timeout = gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), c_increment)
- if gpr_time_cmp(c_timeout, c_deadline) > 0:
- c_timeout = c_deadline
- event = grpc_completion_queue_next(
- self.c_completion_queue, c_timeout, NULL)
- if event.type != GRPC_QUEUE_TIMEOUT or gpr_time_cmp(c_timeout, c_deadline) == 0:
- break;
-
- # Handle any signals
- with gil:
- cpython.PyErr_CheckSignals()
- return self._interpret_event(event)
+ return self._interpret_event(_next(self.c_completion_queue, deadline))
def shutdown(self):
with nogil:
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pxd b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pxd
new file mode 100644
index 0000000..f5688d0
--- /dev/null
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pxd
@@ -0,0 +1,152 @@
+# 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.
+# distutils: language=c++
+
+from libc.stdint cimport uint32_t
+
+cdef extern from "grpc/impl/codegen/slice.h":
+ struct grpc_slice_buffer:
+ int count
+
+cdef extern from "src/core/lib/iomgr/error.h":
+ struct grpc_error:
+ pass
+
+cdef extern from "src/core/lib/iomgr/gevent_util.h":
+ grpc_error* grpc_socket_error(char* error)
+ char* grpc_slice_buffer_start(grpc_slice_buffer* buffer, int i)
+ int grpc_slice_buffer_length(grpc_slice_buffer* buffer, int i)
+
+cdef extern from "src/core/lib/iomgr/sockaddr.h":
+ ctypedef struct grpc_sockaddr:
+ pass
+
+cdef extern from "src/core/lib/iomgr/resolve_address.h":
+ ctypedef struct grpc_resolved_addresses:
+ size_t naddrs
+ grpc_resolved_address* addrs
+
+ ctypedef struct grpc_resolved_address:
+ char[128] addr
+ size_t len
+
+cdef extern from "src/core/lib/iomgr/resolve_address_custom.h":
+ struct grpc_custom_resolver:
+ pass
+
+ struct grpc_custom_resolver_vtable:
+ grpc_error* (*resolve)(char* host, char* port, grpc_resolved_addresses** res);
+ void (*resolve_async)(grpc_custom_resolver* resolver, char* host, char* port);
+
+ void grpc_custom_resolve_callback(grpc_custom_resolver* resolver,
+ grpc_resolved_addresses* result,
+ grpc_error* error);
+
+cdef extern from "src/core/lib/iomgr/tcp_custom.h":
+ struct grpc_custom_socket:
+ void* impl
+ # We don't care about the rest of the fields
+ ctypedef void (*grpc_custom_connect_callback)(grpc_custom_socket* socket,
+ grpc_error* error)
+ ctypedef void (*grpc_custom_write_callback)(grpc_custom_socket* socket,
+ grpc_error* error)
+ ctypedef void (*grpc_custom_read_callback)(grpc_custom_socket* socket,
+ size_t nread, grpc_error* error)
+ ctypedef void (*grpc_custom_accept_callback)(grpc_custom_socket* socket,
+ grpc_custom_socket* client,
+ grpc_error* error)
+ ctypedef void (*grpc_custom_close_callback)(grpc_custom_socket* socket)
+
+ struct grpc_socket_vtable:
+ grpc_error* (*init)(grpc_custom_socket* socket, int domain);
+ void (*connect)(grpc_custom_socket* socket, const grpc_sockaddr* addr,
+ size_t len, grpc_custom_connect_callback cb);
+ void (*destroy)(grpc_custom_socket* socket);
+ void (*shutdown)(grpc_custom_socket* socket);
+ void (*close)(grpc_custom_socket* socket, grpc_custom_close_callback cb);
+ void (*write)(grpc_custom_socket* socket, grpc_slice_buffer* slices,
+ grpc_custom_write_callback cb);
+ void (*read)(grpc_custom_socket* socket, char* buffer, size_t length,
+ grpc_custom_read_callback cb);
+ grpc_error* (*getpeername)(grpc_custom_socket* socket,
+ const grpc_sockaddr* addr, int* len);
+ grpc_error* (*getsockname)(grpc_custom_socket* socket,
+ const grpc_sockaddr* addr, int* len);
+ grpc_error* (*bind)(grpc_custom_socket* socket, const grpc_sockaddr* addr,
+ size_t len, int flags);
+ grpc_error* (*listen)(grpc_custom_socket* socket);
+ void (*accept)(grpc_custom_socket* socket, grpc_custom_socket* client,
+ grpc_custom_accept_callback cb);
+
+cdef extern from "src/core/lib/iomgr/timer_custom.h":
+ struct grpc_custom_timer:
+ void* timer
+ int timeout_ms
+ # We don't care about the rest of the fields
+
+ struct grpc_custom_timer_vtable:
+ void (*start)(grpc_custom_timer* t);
+ void (*stop)(grpc_custom_timer* t);
+
+ void grpc_custom_timer_callback(grpc_custom_timer* t, grpc_error* error);
+
+cdef extern from "src/core/lib/iomgr/pollset_custom.h":
+ struct grpc_custom_poller_vtable:
+ void (*init)()
+ void (*poll)(size_t timeout_ms)
+ void (*kick)()
+ void (*shutdown)()
+
+cdef extern from "src/core/lib/iomgr/iomgr_custom.h":
+ void grpc_custom_iomgr_init(grpc_socket_vtable* socket,
+ grpc_custom_resolver_vtable* resolver,
+ grpc_custom_timer_vtable* timer,
+ grpc_custom_poller_vtable* poller);
+
+cdef extern from "src/core/lib/iomgr/sockaddr_utils.h":
+ int grpc_sockaddr_get_port(const grpc_resolved_address *addr);
+ int grpc_sockaddr_to_string(char **out, const grpc_resolved_address *addr,
+ int normalize);
+ void grpc_string_to_sockaddr(grpc_resolved_address *out, char* addr, int port);
+ int grpc_sockaddr_set_port(const grpc_resolved_address *resolved_addr,
+ int port)
+ const char* grpc_sockaddr_get_uri_scheme(const grpc_resolved_address* resolved_addr)
+
+
+cdef class TimerWrapper:
+
+ cdef grpc_custom_timer *c_timer
+ cdef object timer
+ cdef object event
+
+cdef class SocketWrapper:
+ cdef object sockopts
+ cdef object socket
+ cdef object closed
+ cdef grpc_custom_socket *c_socket
+ cdef char* c_buffer
+ cdef size_t len
+ cdef grpc_custom_socket *accepting_socket
+
+ cdef grpc_custom_connect_callback connect_cb
+ cdef grpc_custom_write_callback write_cb
+ cdef grpc_custom_read_callback read_cb
+ cdef grpc_custom_accept_callback accept_cb
+ cdef grpc_custom_close_callback close_cb
+
+
+cdef class ResolveWrapper:
+ cdef grpc_custom_resolver *c_resolver
+ cdef char* c_host
+ cdef char* c_port
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pyx b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pyx
new file mode 100644
index 0000000..31ef671
--- /dev/null
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pyx
@@ -0,0 +1,448 @@
+# Copyright 2018 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.
+# distutils: language=c++
+
+cimport cpython
+from libc cimport string
+from libc.stdlib cimport malloc, free
+import errno
+gevent_g = None
+gevent_socket = None
+gevent_hub = None
+gevent_event = None
+g_event = None
+g_pool = None
+
+cdef grpc_error* grpc_error_none():
+ return <grpc_error*>0
+
+cdef grpc_error* socket_error(str syscall, str err):
+ error_str = "{} failed: {}".format(syscall, err)
+ error_bytes = str_to_bytes(error_str)
+ return grpc_socket_error(error_bytes)
+
+cdef resolved_addr_to_tuple(grpc_resolved_address* address):
+ cdef char* res_str
+ port = grpc_sockaddr_get_port(address)
+ str_len = grpc_sockaddr_to_string(&res_str, address, 0)
+ byte_str = _decode(<bytes>res_str[:str_len])
+ if byte_str.endswith(':' + str(port)):
+ byte_str = byte_str[:(0 - len(str(port)) - 1)]
+ byte_str = byte_str.lstrip('[')
+ byte_str = byte_str.rstrip(']')
+ byte_str = '{}'.format(byte_str)
+ return byte_str, port
+
+cdef sockaddr_to_tuple(const grpc_sockaddr* address, size_t length):
+ cdef grpc_resolved_address c_addr
+ string.memcpy(<void*>c_addr.addr, <void*> address, length)
+ c_addr.len = length
+ return resolved_addr_to_tuple(&c_addr)
+
+cdef sockaddr_is_ipv4(const grpc_sockaddr* address, size_t length):
+ cdef grpc_resolved_address c_addr
+ string.memcpy(<void*>c_addr.addr, <void*> address, length)
+ c_addr.len = length
+ return grpc_sockaddr_get_uri_scheme(&c_addr) == b'ipv4'
+
+cdef grpc_resolved_addresses* tuples_to_resolvaddr(tups):
+ cdef grpc_resolved_addresses* addresses
+ tups_set = set((tup[4][0], tup[4][1]) for tup in tups)
+ addresses = <grpc_resolved_addresses*> malloc(sizeof(grpc_resolved_addresses))
+ addresses.naddrs = len(tups_set)
+ addresses.addrs = <grpc_resolved_address*> malloc(sizeof(grpc_resolved_address) * len(tups_set))
+ i = 0
+ for tup in set(tups_set):
+ hostname = str_to_bytes(tup[0])
+ grpc_string_to_sockaddr(&addresses.addrs[i], hostname, tup[1])
+ i += 1
+ return addresses
+
+def _spawn_greenlet(*args):
+ greenlet = g_pool.spawn(*args)
+
+###############################
+### socket implementation ###
+###############################
+
+cdef class SocketWrapper:
+ def __cinit__(self):
+ self.sockopts = []
+ self.socket = None
+ self.c_socket = NULL
+ self.c_buffer = NULL
+ self.len = 0
+
+cdef grpc_error* socket_init(grpc_custom_socket* socket, int domain) with gil:
+ sw = SocketWrapper()
+ sw.c_socket = socket
+ sw.sockopts = []
+ cpython.Py_INCREF(sw)
+ # Python doesn't support AF_UNSPEC sockets, so we defer creation until
+ # bind/connect when we know what type of socket we need
+ sw.socket = None
+ sw.closed = False
+ sw.accepting_socket = NULL
+ socket.impl = <void*>sw
+ return grpc_error_none()
+
+cdef socket_connect_async_cython(SocketWrapper socket_wrapper, addr_tuple):
+ try:
+ socket_wrapper.socket.connect(addr_tuple)
+ socket_wrapper.connect_cb(<grpc_custom_socket*>socket_wrapper.c_socket,
+ grpc_error_none())
+ except IOError as io_error:
+ socket_wrapper.connect_cb(<grpc_custom_socket*>socket_wrapper.c_socket,
+ socket_error("connect", str(io_error)))
+ g_event.set()
+
+def socket_connect_async(socket_wrapper, addr_tuple):
+ socket_connect_async_cython(socket_wrapper, addr_tuple)
+
+cdef void socket_connect(grpc_custom_socket* socket, const grpc_sockaddr* addr,
+ size_t addr_len,
+ grpc_custom_connect_callback cb) with gil:
+ py_socket = None
+ socket_wrapper = <SocketWrapper>socket.impl
+ socket_wrapper.connect_cb = cb
+ addr_tuple = sockaddr_to_tuple(addr, addr_len)
+ if sockaddr_is_ipv4(addr, addr_len):
+ py_socket = gevent_socket.socket(gevent_socket.AF_INET)
+ else:
+ py_socket = gevent_socket.socket(gevent_socket.AF_INET6)
+ applysockopts(py_socket)
+ socket_wrapper.socket = py_socket
+ _spawn_greenlet(socket_connect_async, socket_wrapper, addr_tuple)
+
+cdef void socket_destroy(grpc_custom_socket* socket) with gil:
+ cpython.Py_DECREF(<SocketWrapper>socket.impl)
+
+cdef void socket_shutdown(grpc_custom_socket* socket) with gil:
+ try:
+ (<SocketWrapper>socket.impl).socket.shutdown(gevent_socket.SHUT_RDWR)
+ except IOError as io_error:
+ if io_error.errno != errno.ENOTCONN:
+ raise io_error
+
+cdef void socket_close(grpc_custom_socket* socket,
+ grpc_custom_close_callback cb) with gil:
+ socket_wrapper = (<SocketWrapper>socket.impl)
+ if socket_wrapper.socket is not None:
+ socket_wrapper.socket.close()
+ socket_wrapper.closed = True
+ socket_wrapper.close_cb = cb
+ # Delay the close callback until the accept() call has picked it up
+ if socket_wrapper.accepting_socket != NULL:
+ return
+ socket_wrapper.close_cb(socket)
+
+def socket_sendmsg(socket, write_bytes):
+ try:
+ return socket.sendmsg(write_bytes)
+ except AttributeError:
+ # sendmsg not available on all Pythons/Platforms
+ return socket.send(b''.join(write_bytes))
+
+cdef socket_write_async_cython(SocketWrapper socket_wrapper, write_bytes):
+ try:
+ while write_bytes:
+ sent_byte_count = socket_sendmsg(socket_wrapper.socket, write_bytes)
+ while sent_byte_count > 0:
+ if sent_byte_count < len(write_bytes[0]):
+ write_bytes[0] = write_bytes[0][sent_byte_count:]
+ sent_byte_count = 0
+ else:
+ sent_byte_count -= len(write_bytes[0])
+ write_bytes = write_bytes[1:]
+ socket_wrapper.write_cb(<grpc_custom_socket*>socket_wrapper.c_socket,
+ grpc_error_none())
+ except IOError as io_error:
+ socket_wrapper.write_cb(<grpc_custom_socket*>socket_wrapper.c_socket,
+ socket_error("send", str(io_error)))
+ g_event.set()
+
+def socket_write_async(socket_wrapper, write_bytes):
+ socket_write_async_cython(socket_wrapper, write_bytes)
+
+cdef void socket_write(grpc_custom_socket* socket, grpc_slice_buffer* buffer,
+ grpc_custom_write_callback cb) with gil:
+ cdef char* start
+ sw = <SocketWrapper>socket.impl
+ sw.write_cb = cb
+ write_bytes = []
+ for i in range(buffer.count):
+ start = grpc_slice_buffer_start(buffer, i)
+ length = grpc_slice_buffer_length(buffer, i)
+ write_bytes.append(<bytes>start[:length])
+ _spawn_greenlet(socket_write_async, <SocketWrapper>socket.impl, write_bytes)
+
+cdef socket_read_async_cython(SocketWrapper socket_wrapper):
+ cdef char* buff_char_arr
+ try:
+ buff_str = socket_wrapper.socket.recv(socket_wrapper.len)
+ buff_char_arr = buff_str
+ string.memcpy(<void*>socket_wrapper.c_buffer, buff_char_arr, len(buff_str))
+ socket_wrapper.read_cb(<grpc_custom_socket*>socket_wrapper.c_socket,
+ len(buff_str), grpc_error_none())
+ except IOError as io_error:
+ socket_wrapper.read_cb(<grpc_custom_socket*>socket_wrapper.c_socket,
+ -1, socket_error("recv", str(io_error)))
+ g_event.set()
+
+def socket_read_async(socket_wrapper):
+ socket_read_async_cython(socket_wrapper)
+
+cdef void socket_read(grpc_custom_socket* socket, char* buffer,
+ size_t length, grpc_custom_read_callback cb) with gil:
+ sw = <SocketWrapper>socket.impl
+ sw.read_cb = cb
+ sw.c_buffer = buffer
+ sw.len = length
+ _spawn_greenlet(socket_read_async, sw)
+
+cdef grpc_error* socket_getpeername(grpc_custom_socket* socket,
+ const grpc_sockaddr* addr,
+ int* length) with gil:
+ cdef char* src_buf
+ peer = (<SocketWrapper>socket.impl).socket.getpeername()
+
+ cdef grpc_resolved_address c_addr
+ hostname = str_to_bytes(peer[0])
+ grpc_string_to_sockaddr(&c_addr, hostname, peer[1])
+ string.memcpy(<void*>addr, <void*>c_addr.addr, c_addr.len)
+ length[0] = c_addr.len
+ return grpc_error_none()
+
+cdef grpc_error* socket_getsockname(grpc_custom_socket* socket,
+ const grpc_sockaddr* addr,
+ int* length) with gil:
+ cdef char* src_buf
+ cdef grpc_resolved_address c_addr
+ if (<SocketWrapper>socket.impl).socket is None:
+ peer = ('0.0.0.0', 0)
+ else:
+ peer = (<SocketWrapper>socket.impl).socket.getsockname()
+ hostname = str_to_bytes(peer[0])
+ grpc_string_to_sockaddr(&c_addr, hostname, peer[1])
+ string.memcpy(<void*>addr, <void*>c_addr.addr, c_addr.len)
+ length[0] = c_addr.len
+ return grpc_error_none()
+
+def applysockopts(s):
+ s.setsockopt(gevent_socket.SOL_SOCKET, gevent_socket.SO_REUSEADDR, 1)
+ s.setsockopt(gevent_socket.IPPROTO_TCP, gevent_socket.TCP_NODELAY, True)
+
+cdef grpc_error* socket_bind(grpc_custom_socket* socket,
+ const grpc_sockaddr* addr,
+ size_t len, int flags) with gil:
+ addr_tuple = sockaddr_to_tuple(addr, len)
+ try:
+ try:
+ py_socket = gevent_socket.socket(gevent_socket.AF_INET)
+ applysockopts(py_socket)
+ py_socket.bind(addr_tuple)
+ except gevent_socket.gaierror as e:
+ py_socket = gevent_socket.socket(gevent_socket.AF_INET6)
+ applysockopts(py_socket)
+ py_socket.bind(addr_tuple)
+ (<SocketWrapper>socket.impl).socket = py_socket
+ except IOError as io_error:
+ return socket_error("bind", str(io_error))
+ else:
+ return grpc_error_none()
+
+cdef grpc_error* socket_listen(grpc_custom_socket* socket) with gil:
+ (<SocketWrapper>socket.impl).socket.listen(50)
+ return grpc_error_none()
+
+cdef void accept_callback_cython(SocketWrapper s):
+ try:
+ conn, address = s.socket.accept()
+ sw = SocketWrapper()
+ sw.closed = False
+ sw.c_socket = s.accepting_socket
+ sw.sockopts = []
+ sw.socket = conn
+ sw.c_socket.impl = <void*>sw
+ sw.accepting_socket = NULL
+ cpython.Py_INCREF(sw)
+ s.accepting_socket = NULL
+ s.accept_cb(<grpc_custom_socket*>s.c_socket, sw.c_socket, grpc_error_none())
+ except IOError as io_error:
+ #TODO actual error
+ s.accepting_socket = NULL
+ s.accept_cb(<grpc_custom_socket*>s.c_socket, s.accepting_socket,
+ socket_error("accept", str(io_error)))
+ if s.closed:
+ s.close_cb(<grpc_custom_socket*>s.c_socket)
+ g_event.set()
+
+def socket_accept_async(s):
+ accept_callback_cython(s)
+
+cdef void socket_accept(grpc_custom_socket* socket, grpc_custom_socket* client,
+ grpc_custom_accept_callback cb) with gil:
+ sw = <SocketWrapper>socket.impl
+ sw.accepting_socket = client
+ sw.accept_cb = cb
+ _spawn_greenlet(socket_accept_async, sw)
+
+#####################################
+######Resolver implementation #######
+#####################################
+
+cdef class ResolveWrapper:
+ def __cinit__(self):
+ self.c_resolver = NULL
+ self.c_host = NULL
+ self.c_port = NULL
+
+cdef socket_resolve_async_cython(ResolveWrapper resolve_wrapper):
+ try:
+ res = gevent_socket.getaddrinfo(resolve_wrapper.c_host, resolve_wrapper.c_port)
+ grpc_custom_resolve_callback(<grpc_custom_resolver*>resolve_wrapper.c_resolver,
+ tuples_to_resolvaddr(res), grpc_error_none())
+ except IOError as io_error:
+ grpc_custom_resolve_callback(<grpc_custom_resolver*>resolve_wrapper.c_resolver,
+ <grpc_resolved_addresses*>0,
+ socket_error("getaddrinfo", str(io_error)))
+ g_event.set()
+
+def socket_resolve_async_python(resolve_wrapper):
+ socket_resolve_async_cython(resolve_wrapper)
+
+cdef void socket_resolve_async(grpc_custom_resolver* r, char* host, char* port) with gil:
+ rw = ResolveWrapper()
+ rw.c_resolver = r
+ rw.c_host = host
+ rw.c_port = port
+ _spawn_greenlet(socket_resolve_async_python, rw)
+
+cdef grpc_error* socket_resolve(char* host, char* port,
+ grpc_resolved_addresses** res) with gil:
+ try:
+ result = gevent_socket.getaddrinfo(host, port)
+ res[0] = tuples_to_resolvaddr(result)
+ return grpc_error_none()
+ except IOError as io_error:
+ return socket_error("getaddrinfo", str(io_error))
+
+###############################
+### timer implementation ######
+###############################
+
+cdef class TimerWrapper:
+ def __cinit__(self, deadline):
+ self.timer = gevent_hub.get_hub().loop.timer(deadline)
+ self.event = None
+
+ def start(self):
+ self.event = gevent_event.Event()
+ self.timer.start(self.on_finish)
+
+ def on_finish(self):
+ grpc_custom_timer_callback(self.c_timer, grpc_error_none())
+ self.timer.stop()
+ g_event.set()
+
+ def stop(self):
+ self.event.set()
+ self.timer.stop()
+
+cdef void timer_start(grpc_custom_timer* t) with gil:
+ timer = TimerWrapper(t.timeout_ms / 1000.0)
+ timer.c_timer = t
+ t.timer = <void*>timer
+ timer.start()
+
+cdef void timer_stop(grpc_custom_timer* t) with gil:
+ time_wrapper = <object>t.timer
+ time_wrapper.stop()
+
+###############################
+### pollset implementation ###
+###############################
+
+cdef void init_loop() with gil:
+ pass
+
+cdef void destroy_loop() with gil:
+ g_pool.join()
+
+cdef void kick_loop() with gil:
+ g_event.set()
+
+cdef void run_loop(size_t timeout_ms) with gil:
+ timeout = timeout_ms / 1000.0
+ if timeout_ms > 0:
+ g_event.wait(timeout)
+ g_event.clear()
+
+###############################
+### Initializer ###############
+###############################
+
+cdef grpc_socket_vtable gevent_socket_vtable
+cdef grpc_custom_resolver_vtable gevent_resolver_vtable
+cdef grpc_custom_timer_vtable gevent_timer_vtable
+cdef grpc_custom_poller_vtable gevent_pollset_vtable
+
+def init_grpc_gevent():
+ # Lazily import gevent
+ global gevent_socket
+ global gevent_g
+ global gevent_hub
+ global gevent_event
+ global g_event
+ global g_pool
+ import gevent
+ gevent_g = gevent
+ import gevent.socket
+ gevent_socket = gevent.socket
+ import gevent.hub
+ gevent_hub = gevent.hub
+ import gevent.event
+ gevent_event = gevent.event
+ import gevent.pool
+
+ g_event = gevent.event.Event()
+ g_pool = gevent.pool.Group()
+ gevent_resolver_vtable.resolve = socket_resolve
+ gevent_resolver_vtable.resolve_async = socket_resolve_async
+
+ gevent_socket_vtable.init = socket_init
+ gevent_socket_vtable.connect = socket_connect
+ gevent_socket_vtable.destroy = socket_destroy
+ gevent_socket_vtable.shutdown = socket_shutdown
+ gevent_socket_vtable.close = socket_close
+ gevent_socket_vtable.write = socket_write
+ gevent_socket_vtable.read = socket_read
+ gevent_socket_vtable.getpeername = socket_getpeername
+ gevent_socket_vtable.getsockname = socket_getsockname
+ gevent_socket_vtable.bind = socket_bind
+ gevent_socket_vtable.listen = socket_listen
+ gevent_socket_vtable.accept = socket_accept
+
+ gevent_timer_vtable.start = timer_start
+ gevent_timer_vtable.stop = timer_stop
+
+ gevent_pollset_vtable.init = init_loop
+ gevent_pollset_vtable.poll = run_loop
+ gevent_pollset_vtable.kick = kick_loop
+ gevent_pollset_vtable.shutdown = destroy_loop
+
+ grpc_custom_iomgr_init(&gevent_socket_vtable,
+ &gevent_resolver_vtable,
+ &gevent_timer_vtable,
+ &gevent_pollset_vtable)
diff --git a/src/python/grpcio/grpc/_cython/cygrpc.pxd b/src/python/grpcio/grpc/_cython/cygrpc.pxd
index b6a794c..c8ace7c 100644
--- a/src/python/grpcio/grpc/_cython/cygrpc.pxd
+++ b/src/python/grpcio/grpc/_cython/cygrpc.pxd
@@ -11,6 +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.
+# distutils: language=c++
include "_cygrpc/grpc.pxi"
@@ -27,3 +28,5 @@
include "_cygrpc/server.pxd.pxi"
include "_cygrpc/tag.pxd.pxi"
include "_cygrpc/time.pxd.pxi"
+
+include "_cygrpc/grpc_gevent.pxd"
diff --git a/src/python/grpcio/grpc/_cython/cygrpc.pyx b/src/python/grpcio/grpc/_cython/cygrpc.pyx
index 2ee2e6b..f5f08fc 100644
--- a/src/python/grpcio/grpc/_cython/cygrpc.pyx
+++ b/src/python/grpcio/grpc/_cython/cygrpc.pyx
@@ -11,6 +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.
+# distutils: language=c++
cimport cpython
@@ -35,6 +36,8 @@
include "_cygrpc/tag.pyx.pxi"
include "_cygrpc/time.pyx.pxi"
+include "_cygrpc/grpc_gevent.pyx"
+
#
# initialize gRPC
#
diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py
index 4a69d85..ad53f60 100644
--- a/src/python/grpcio/grpc/_grpcio_metadata.py
+++ b/src/python/grpcio/grpc/_grpcio_metadata.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc/_grpcio_metadata.py.template`!!!
-__version__ = """1.11.0.dev0"""
+__version__ = """1.13.0.dev0"""
diff --git a/src/python/grpcio/grpc/_interceptor.py b/src/python/grpcio/grpc/_interceptor.py
index d029472..f465e35 100644
--- a/src/python/grpcio/grpc/_interceptor.py
+++ b/src/python/grpcio/grpc/_interceptor.py
@@ -334,6 +334,19 @@
else:
return thunk(method)
+ def _close(self):
+ self._channel.close()
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, exc_type, exc_val, exc_tb):
+ self._close()
+ return False
+
+ def close(self):
+ self._channel.close()
+
def intercept_channel(channel, *interceptors):
for interceptor in reversed(list(interceptors)):
diff --git a/src/python/grpcio/grpc/_server.py b/src/python/grpcio/grpc/_server.py
index c988e0c..d849cad 100644
--- a/src/python/grpcio/grpc/_server.py
+++ b/src/python/grpcio/grpc/_server.py
@@ -780,14 +780,8 @@
state.stage = _ServerStage.STARTED
_request_call(state)
- def cleanup_server(timeout):
- if timeout is None:
- _stop(state, _UNEXPECTED_EXIT_SERVER_GRACE).wait()
- else:
- _stop(state, timeout).wait()
-
- thread = _common.CleanupThread(
- cleanup_server, target=_serve, args=(state,))
+ thread = threading.Thread(target=_serve, args=(state,))
+ thread.daemon = True
thread.start()
diff --git a/src/python/grpcio/grpc/beta/_server_adaptations.py b/src/python/grpcio/grpc/beta/_server_adaptations.py
index 3c04fd7..ccafec8 100644
--- a/src/python/grpcio/grpc/beta/_server_adaptations.py
+++ b/src/python/grpcio/grpc/beta/_server_adaptations.py
@@ -168,11 +168,8 @@
return
request_consumer.terminate()
- def stop_request_pipe(timeout): # pylint: disable=unused-argument
- thread_joined.set()
-
- request_pipe_thread = _common.CleanupThread(
- stop_request_pipe, target=pipe_requests)
+ request_pipe_thread = threading.Thread(target=pipe_requests)
+ request_pipe_thread.daemon = True
request_pipe_thread.start()
diff --git a/src/python/grpcio/grpc/experimental/__init__.py b/src/python/grpcio/grpc/experimental/__init__.py
new file mode 100644
index 0000000..dcec322
--- /dev/null
+++ b/src/python/grpcio/grpc/experimental/__init__.py
@@ -0,0 +1,17 @@
+# Copyright 2018 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.
+"""gRPC's experimental APIs.
+
+These APIs are subject to be removed during any minor version release.
+"""
diff --git a/src/python/grpcio/grpc/experimental/gevent.py b/src/python/grpcio/grpc/experimental/gevent.py
new file mode 100644
index 0000000..159d612
--- /dev/null
+++ b/src/python/grpcio/grpc/experimental/gevent.py
@@ -0,0 +1,27 @@
+# Copyright 2018 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.
+"""gRPC's Python gEvent APIs."""
+
+from grpc._cython import cygrpc as _cygrpc
+
+
+def init_gevent():
+ """Patches gRPC's libraries to be compatible with gevent.
+
+ This must be called AFTER the python standard lib has been patched,
+ but BEFORE creating and gRPC objects.
+
+ In order for progress to be made, the application must drive the event loop.
+ """
+ _cygrpc.init_grpc_gevent()
diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py
index 9f4aaff..699d504 100644
--- a/src/python/grpcio/grpc_core_dependencies.py
+++ b/src/python/grpcio/grpc_core_dependencies.py
@@ -296,9 +296,9 @@
'third_party/nanopb/pb_decode.c',
'third_party/nanopb/pb_encode.c',
'src/core/tsi/transport_security.cc',
- 'src/core/tsi/transport_security_adapter.cc',
'src/core/ext/transport/chttp2/client/insecure/channel_create.cc',
'src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc',
+ 'src/core/ext/transport/chttp2/client/authority.cc',
'src/core/ext/transport/chttp2/client/chttp2_connector.cc',
'src/core/ext/filters/client_channel/backup_poller.cc',
'src/core/ext/filters/client_channel/channel_connectivity.cc',
@@ -343,7 +343,6 @@
'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c',
'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc',
'src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc',
- 'src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc',
'src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc',
@@ -356,6 +355,7 @@
'src/core/ext/census/grpc_context.cc',
'src/core/ext/filters/max_age/max_age_filter.cc',
'src/core/ext/filters/message_size/message_size_filter.cc',
+ 'src/core/ext/filters/http/client_authority_filter.cc',
'src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc',
'src/core/ext/filters/workarounds/workaround_utils.cc',
'src/core/plugin_registry/grpc_plugin_registry.cc',
diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py
index 32e8249..57dc26d 100644
--- a/src/python/grpcio/grpc_version.py
+++ b/src/python/grpcio/grpc_version.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_version.py.template`!!!
-VERSION = '1.11.0.dev0'
+VERSION = '1.13.0.dev0'
diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py
index ad4c85c..ba0d4a3 100644
--- a/src/python/grpcio_health_checking/grpc_version.py
+++ b/src/python/grpcio_health_checking/grpc_version.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!!
-VERSION = '1.11.0.dev0'
+VERSION = '1.13.0.dev0'
diff --git a/src/python/grpcio_health_checking/setup.py b/src/python/grpcio_health_checking/setup.py
index 60d309e..35c0982 100644
--- a/src/python/grpcio_health_checking/setup.py
+++ b/src/python/grpcio_health_checking/setup.py
@@ -57,7 +57,7 @@
}
INSTALL_REQUIRES = (
- 'protobuf>=3.5.0.post1',
+ 'protobuf>=3.5.2.post1',
'grpcio>={version}'.format(version=grpc_version.VERSION),
)
diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py
index 6322d84..ea2878d 100644
--- a/src/python/grpcio_reflection/grpc_version.py
+++ b/src/python/grpcio_reflection/grpc_version.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_reflection/grpc_version.py.template`!!!
-VERSION = '1.11.0.dev0'
+VERSION = '1.13.0.dev0'
diff --git a/src/python/grpcio_reflection/setup.py b/src/python/grpcio_reflection/setup.py
index 10c4c38..589d0ff 100644
--- a/src/python/grpcio_reflection/setup.py
+++ b/src/python/grpcio_reflection/setup.py
@@ -58,7 +58,7 @@
}
INSTALL_REQUIRES = (
- 'protobuf>=3.5.0.post1',
+ 'protobuf>=3.5.2.post1',
'grpcio>={version}'.format(version=grpc_version.VERSION),
)
diff --git a/src/python/grpcio_testing/grpc_testing/_channel/_channel.py b/src/python/grpcio_testing/grpc_testing/_channel/_channel.py
index b015b8d..0c1941e 100644
--- a/src/python/grpcio_testing/grpc_testing/_channel/_channel.py
+++ b/src/python/grpcio_testing/grpc_testing/_channel/_channel.py
@@ -56,6 +56,21 @@
response_deserializer=None):
return _multi_callable.StreamStream(method, self._state)
+ def _close(self):
+ # TODO(https://github.com/grpc/grpc/issues/12531): Decide what
+ # action to take here, if any?
+ pass
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, exc_type, exc_val, exc_tb):
+ self._close()
+ return False
+
+ def close(self):
+ self._close()
+
def take_unary_unary(self, method_descriptor):
return _channel_rpc.unary_unary(self._state, method_descriptor)
diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py
index 1e75fea..02f19f2 100644
--- a/src/python/grpcio_testing/grpc_version.py
+++ b/src/python/grpcio_testing/grpc_version.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_testing/grpc_version.py.template`!!!
-VERSION = '1.11.0.dev0'
+VERSION = '1.13.0.dev0'
diff --git a/src/python/grpcio_testing/setup.py b/src/python/grpcio_testing/setup.py
index 5a9d593..eb480a5 100644
--- a/src/python/grpcio_testing/setup.py
+++ b/src/python/grpcio_testing/setup.py
@@ -29,7 +29,7 @@
}
INSTALL_REQUIRES = (
- 'protobuf>=3.5.0.post1',
+ 'protobuf>=3.5.2.post1',
'grpcio>={version}'.format(version=grpc_version.VERSION),
)
diff --git a/src/python/grpcio_tests/commands.py b/src/python/grpcio_tests/commands.py
index 93f8457..42e01c1 100644
--- a/src/python/grpcio_tests/commands.py
+++ b/src/python/grpcio_tests/commands.py
@@ -108,6 +108,57 @@
self.distribution.fetch_build_eggs(self.distribution.tests_require)
+class TestGevent(setuptools.Command):
+ """Command to run tests w/gevent."""
+
+ BANNED_TESTS = (
+ # These tests send a lot of RPCs and are really slow on gevent. They will
+ # eventually succeed, but need to dig into performance issues.
+ 'unit._cython._no_messages_server_completion_queue_per_call_test.Test.test_rpcs',
+ 'unit._cython._no_messages_single_server_completion_queue_test.Test.test_rpcs',
+ # I have no idea why this doesn't work in gevent, but it shouldn't even be
+ # using the c-core
+ 'testing._client_test.ClientTest.test_infinite_request_stream_real_time',
+ # TODO(https://github.com/grpc/grpc/issues/14789) enable this test
+ 'unit._server_ssl_cert_config_test',
+ # TODO(https://github.com/grpc/grpc/issues/14901) enable this test
+ 'protoc_plugin._python_plugin_test.PythonPluginTest',
+ # Beta API is unsupported for gevent
+ 'protoc_plugin.beta_python_plugin_test',
+ 'unit.beta._beta_features_test',
+ )
+ description = 'run tests with gevent. Assumes grpc/gevent are installed'
+ user_options = []
+
+ def initialize_options(self):
+ pass
+
+ def finalize_options(self):
+ # distutils requires this override.
+ pass
+
+ def run(self):
+ from gevent import monkey
+ monkey.patch_all()
+
+ import tests
+
+ import grpc.experimental.gevent
+ grpc.experimental.gevent.init_gevent()
+
+ import gevent
+
+ import tests
+ loader = tests.Loader()
+ loader.loadTestsFromNames(['tests'])
+ runner = tests.Runner()
+ runner.skip_tests(self.BANNED_TESTS)
+ result = gevent.spawn(runner.run, loader.suite)
+ result.join()
+ if not result.value.wasSuccessful():
+ sys.exit('Test failure')
+
+
class RunInterop(test.test):
description = 'run interop test client/server'
diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py
index 0cd7bd2..9d2e416 100644
--- a/src/python/grpcio_tests/grpc_version.py
+++ b/src/python/grpcio_tests/grpc_version.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_tests/grpc_version.py.template`!!!
-VERSION = '1.11.0.dev0'
+VERSION = '1.13.0.dev0'
diff --git a/src/python/grpcio_tests/setup.py b/src/python/grpcio_tests/setup.py
index 250df65..98ac19d 100644
--- a/src/python/grpcio_tests/setup.py
+++ b/src/python/grpcio_tests/setup.py
@@ -41,7 +41,7 @@
'grpcio>={version}'.format(version=grpc_version.VERSION),
'grpcio-tools>={version}'.format(version=grpc_version.VERSION),
'grpcio-health-checking>={version}'.format(version=grpc_version.VERSION),
- 'oauth2client>=1.4.7', 'protobuf>=3.5.0.post1', 'six>=1.10',
+ 'oauth2client>=1.4.7', 'protobuf>=3.5.2.post1', 'six>=1.10',
'google-auth>=1.0.0', 'requests>=2.14.2')
COMMAND_CLASS = {
@@ -50,7 +50,8 @@
'build_package_protos': grpc_tools.command.BuildPackageProtos,
'build_py': commands.BuildPy,
'run_interop': commands.RunInterop,
- 'test_lite': commands.TestLite
+ 'test_lite': commands.TestLite,
+ 'test_gevent': commands.TestGevent,
}
PACKAGE_DATA = {
diff --git a/src/python/grpcio_tests/tests/_loader.py b/src/python/grpcio_tests/tests/_loader.py
index 3168091..be0af646 100644
--- a/src/python/grpcio_tests/tests/_loader.py
+++ b/src/python/grpcio_tests/tests/_loader.py
@@ -54,7 +54,7 @@
for module in modules:
try:
package_paths = module.__path__
- except:
+ except AttributeError:
continue
self.walk_packages(package_paths)
coverage_context.stop()
diff --git a/src/python/grpcio_tests/tests/_result.py b/src/python/grpcio_tests/tests/_result.py
index 9907c4e..b105f18 100644
--- a/src/python/grpcio_tests/tests/_result.py
+++ b/src/python/grpcio_tests/tests/_result.py
@@ -46,7 +46,7 @@
None.
"""
- class Kind:
+ class Kind(object):
UNTESTED = 'untested'
RUNNING = 'running'
ERROR = 'error'
@@ -257,7 +257,7 @@
#coverage.Coverage().combine()
-class _Colors:
+class _Colors(object):
"""Namespaced constants for terminal color magic numbers."""
HEADER = '\033[95m'
INFO = '\033[94m'
diff --git a/src/python/grpcio_tests/tests/_runner.py b/src/python/grpcio_tests/tests/_runner.py
index 8e27dc6..eaaa027 100644
--- a/src/python/grpcio_tests/tests/_runner.py
+++ b/src/python/grpcio_tests/tests/_runner.py
@@ -117,6 +117,12 @@
class Runner(object):
+ def __init__(self):
+ self._skipped_tests = []
+
+ def skip_tests(self, tests):
+ self._skipped_tests = tests
+
def run(self, suite):
"""See setuptools' test_runner setup argument for information."""
# only run test cases with id starting with given prefix
@@ -181,27 +187,31 @@
# Run the tests
result.startTestRun()
for augmented_case in augmented_cases:
- sys.stdout.write('Running {}\n'.format(
- augmented_case.case.id()))
- sys.stdout.flush()
- case_thread = threading.Thread(
- target=augmented_case.case.run, args=(result,))
- try:
- with stdout_pipe, stderr_pipe:
- case_thread.start()
- while case_thread.is_alive():
- check_kill_self()
- time.sleep(0)
- case_thread.join()
- except:
- # re-raise the exception after forcing the with-block to end
- raise
- result.set_output(augmented_case.case, stdout_pipe.output(),
- stderr_pipe.output())
- sys.stdout.write(result_out.getvalue())
- sys.stdout.flush()
- result_out.truncate(0)
- check_kill_self()
+ for skipped_test in self._skipped_tests:
+ if skipped_test in augmented_case.case.id():
+ break
+ else:
+ sys.stdout.write('Running {}\n'.format(
+ augmented_case.case.id()))
+ sys.stdout.flush()
+ case_thread = threading.Thread(
+ target=augmented_case.case.run, args=(result,))
+ try:
+ with stdout_pipe, stderr_pipe:
+ case_thread.start()
+ while case_thread.is_alive():
+ check_kill_self()
+ time.sleep(0)
+ case_thread.join()
+ except:
+ # re-raise the exception after forcing the with-block to end
+ raise
+ result.set_output(augmented_case.case, stdout_pipe.output(),
+ stderr_pipe.output())
+ sys.stdout.write(result_out.getvalue())
+ sys.stdout.flush()
+ result_out.truncate(0)
+ check_kill_self()
result.stopTestRun()
stdout_pipe.close()
stderr_pipe.close()
diff --git a/src/python/grpcio_tests/tests/interop/_insecure_intraop_test.py b/src/python/grpcio_tests/tests/interop/_insecure_intraop_test.py
index 8d464b2..ace15be 100644
--- a/src/python/grpcio_tests/tests/interop/_insecure_intraop_test.py
+++ b/src/python/grpcio_tests/tests/interop/_insecure_intraop_test.py
@@ -36,6 +36,9 @@
self.stub = test_pb2_grpc.TestServiceStub(
grpc.insecure_channel('localhost:{}'.format(port)))
+ def tearDown(self):
+ self.server.stop(None)
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/interop/_secure_intraop_test.py b/src/python/grpcio_tests/tests/interop/_secure_intraop_test.py
index c891359..e27e551 100644
--- a/src/python/grpcio_tests/tests/interop/_secure_intraop_test.py
+++ b/src/python/grpcio_tests/tests/interop/_secure_intraop_test.py
@@ -45,6 +45,9 @@
_SERVER_HOST_OVERRIDE,
),)))
+ def tearDown(self):
+ self.server.stop(None)
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/interop/client.py b/src/python/grpcio_tests/tests/interop/client.py
index 3780ed9..698c370 100644
--- a/src/python/grpcio_tests/tests/interop/client.py
+++ b/src/python/grpcio_tests/tests/interop/client.py
@@ -66,10 +66,6 @@
return parser.parse_args()
-def _application_default_credentials():
- return oauth2client_client.GoogleCredentials.get_application_default()
-
-
def _stub(args):
target = '{}:{}'.format(args.server_host, args.server_port)
if args.test_case == 'oauth2_auth_token':
diff --git a/src/python/grpcio_tests/tests/protoc_plugin/_python_plugin_test.py b/src/python/grpcio_tests/tests/protoc_plugin/_python_plugin_test.py
index 6d85f43..00e60b4 100644
--- a/src/python/grpcio_tests/tests/protoc_plugin/_python_plugin_test.py
+++ b/src/python/grpcio_tests/tests/protoc_plugin/_python_plugin_test.py
@@ -237,6 +237,7 @@
self.assertIsNotNone(service.servicer_methods)
self.assertIsNotNone(service.server)
self.assertIsNotNone(service.stub)
+ service.server.stop(None)
def testIncompleteServicer(self):
service = _CreateIncompleteService()
@@ -245,6 +246,7 @@
service.stub.UnaryCall(request)
self.assertIs(exception_context.exception.code(),
grpc.StatusCode.UNIMPLEMENTED)
+ service.server.stop(None)
def testUnaryCall(self):
service = _CreateService()
@@ -253,6 +255,7 @@
expected_response = service.servicer_methods.UnaryCall(
request, 'not a real context!')
self.assertEqual(expected_response, response)
+ service.server.stop(None)
def testUnaryCallFuture(self):
service = _CreateService()
@@ -264,6 +267,7 @@
expected_response = service.servicer_methods.UnaryCall(
request, 'not a real RpcContext!')
self.assertEqual(expected_response, response)
+ service.server.stop(None)
def testUnaryCallFutureExpired(self):
service = _CreateService()
@@ -276,6 +280,7 @@
self.assertIs(exception_context.exception.code(),
grpc.StatusCode.DEADLINE_EXCEEDED)
self.assertIs(response_future.code(), grpc.StatusCode.DEADLINE_EXCEEDED)
+ service.server.stop(None)
def testUnaryCallFutureCancelled(self):
service = _CreateService()
@@ -285,6 +290,7 @@
response_future.cancel()
self.assertTrue(response_future.cancelled())
self.assertIs(response_future.code(), grpc.StatusCode.CANCELLED)
+ service.server.stop(None)
def testUnaryCallFutureFailed(self):
service = _CreateService()
@@ -293,6 +299,7 @@
response_future = service.stub.UnaryCall.future(request)
self.assertIsNotNone(response_future.exception())
self.assertIs(response_future.code(), grpc.StatusCode.UNKNOWN)
+ service.server.stop(None)
def testStreamingOutputCall(self):
service = _CreateService()
@@ -303,6 +310,7 @@
for expected_response, response in moves.zip_longest(
expected_responses, responses):
self.assertEqual(expected_response, response)
+ service.server.stop(None)
def testStreamingOutputCallExpired(self):
service = _CreateService()
@@ -314,6 +322,7 @@
list(responses)
self.assertIs(exception_context.exception.code(),
grpc.StatusCode.DEADLINE_EXCEEDED)
+ service.server.stop(None)
def testStreamingOutputCallCancelled(self):
service = _CreateService()
@@ -324,6 +333,7 @@
with self.assertRaises(grpc.RpcError) as exception_context:
next(responses)
self.assertIs(responses.code(), grpc.StatusCode.CANCELLED)
+ service.server.stop(None)
def testStreamingOutputCallFailed(self):
service = _CreateService()
@@ -335,6 +345,7 @@
next(responses)
self.assertIs(exception_context.exception.code(),
grpc.StatusCode.UNKNOWN)
+ service.server.stop(None)
def testStreamingInputCall(self):
service = _CreateService()
@@ -343,6 +354,7 @@
expected_response = service.servicer_methods.StreamingInputCall(
_streaming_input_request_iterator(), 'not a real RpcContext!')
self.assertEqual(expected_response, response)
+ service.server.stop(None)
def testStreamingInputCallFuture(self):
service = _CreateService()
@@ -353,6 +365,7 @@
expected_response = service.servicer_methods.StreamingInputCall(
_streaming_input_request_iterator(), 'not a real RpcContext!')
self.assertEqual(expected_response, response)
+ service.server.stop(None)
def testStreamingInputCallFutureExpired(self):
service = _CreateService()
@@ -367,6 +380,7 @@
grpc.StatusCode.DEADLINE_EXCEEDED)
self.assertIs(exception_context.exception.code(),
grpc.StatusCode.DEADLINE_EXCEEDED)
+ service.server.stop(None)
def testStreamingInputCallFutureCancelled(self):
service = _CreateService()
@@ -377,6 +391,7 @@
self.assertTrue(response_future.cancelled())
with self.assertRaises(grpc.FutureCancelledError):
response_future.result()
+ service.server.stop(None)
def testStreamingInputCallFutureFailed(self):
service = _CreateService()
@@ -385,6 +400,7 @@
_streaming_input_request_iterator())
self.assertIsNotNone(response_future.exception())
self.assertIs(response_future.code(), grpc.StatusCode.UNKNOWN)
+ service.server.stop(None)
def testFullDuplexCall(self):
service = _CreateService()
@@ -394,6 +410,7 @@
for expected_response, response in moves.zip_longest(
expected_responses, responses):
self.assertEqual(expected_response, response)
+ service.server.stop(None)
def testFullDuplexCallExpired(self):
request_iterator = _full_duplex_request_iterator()
@@ -405,6 +422,7 @@
list(responses)
self.assertIs(exception_context.exception.code(),
grpc.StatusCode.DEADLINE_EXCEEDED)
+ service.server.stop(None)
def testFullDuplexCallCancelled(self):
service = _CreateService()
@@ -416,6 +434,7 @@
next(responses)
self.assertIs(exception_context.exception.code(),
grpc.StatusCode.CANCELLED)
+ service.server.stop(None)
def testFullDuplexCallFailed(self):
request_iterator = _full_duplex_request_iterator()
@@ -426,6 +445,7 @@
next(responses)
self.assertIs(exception_context.exception.code(),
grpc.StatusCode.UNKNOWN)
+ service.server.stop(None)
def testHalfDuplexCall(self):
service = _CreateService()
@@ -445,6 +465,7 @@
for expected_response, response in moves.zip_longest(
expected_responses, responses):
self.assertEqual(expected_response, response)
+ service.server.stop(None)
def testHalfDuplexCallWedged(self):
condition = threading.Condition()
@@ -478,6 +499,7 @@
next(responses)
self.assertIs(exception_context.exception.code(),
grpc.StatusCode.DEADLINE_EXCEEDED)
+ service.server.stop(None)
if __name__ == '__main__':
diff --git a/src/python/grpcio_tests/tests/protoc_plugin/_split_definitions_test.py b/src/python/grpcio_tests/tests/protoc_plugin/_split_definitions_test.py
index ab33775..e21ea00 100644
--- a/src/python/grpcio_tests/tests/protoc_plugin/_split_definitions_test.py
+++ b/src/python/grpcio_tests/tests/protoc_plugin/_split_definitions_test.py
@@ -271,6 +271,7 @@
stub = services_module.TestServiceStub(channel)
response = stub.Call(self._messages_pb2.Request())
self.assertEqual(self._messages_pb2.Response(), response)
+ server.stop(None)
def _create_test_case_class(split_proto, protoc_style):
diff --git a/src/python/grpcio_tests/tests/protoc_plugin/beta_python_plugin_test.py b/src/python/grpcio_tests/tests/protoc_plugin/beta_python_plugin_test.py
index ad0ecf0..b46e533 100644
--- a/src/python/grpcio_tests/tests/protoc_plugin/beta_python_plugin_test.py
+++ b/src/python/grpcio_tests/tests/protoc_plugin/beta_python_plugin_test.py
@@ -329,9 +329,7 @@
_packagify(self._python_out)
- with _system_path([
- self._python_out,
- ]):
+ with _system_path([self._python_out]):
self._payload_pb2 = importlib.import_module(_PAYLOAD_PB2)
self._requests_pb2 = importlib.import_module(_REQUESTS_PB2)
self._responses_pb2 = importlib.import_module(_RESPONSES_PB2)
diff --git a/src/python/grpcio_tests/tests/qps/benchmark_client.py b/src/python/grpcio_tests/tests/qps/benchmark_client.py
index e6392a8..0488450 100644
--- a/src/python/grpcio_tests/tests/qps/benchmark_client.py
+++ b/src/python/grpcio_tests/tests/qps/benchmark_client.py
@@ -22,7 +22,7 @@
import grpc
from src.proto.grpc.testing import messages_pb2
-from src.proto.grpc.testing import services_pb2_grpc
+from src.proto.grpc.testing import benchmark_service_pb2_grpc
from tests.unit import resources
from tests.unit import test_common
@@ -58,7 +58,8 @@
if config.payload_config.WhichOneof('payload') == 'simple_params':
self._generic = False
- self._stub = services_pb2_grpc.BenchmarkServiceStub(channel)
+ self._stub = benchmark_service_pb2_grpc.BenchmarkServiceStub(
+ channel)
payload = messages_pb2.Payload(
body='\0' * config.payload_config.simple_params.req_size)
self._request = messages_pb2.SimpleRequest(
diff --git a/src/python/grpcio_tests/tests/qps/benchmark_server.py b/src/python/grpcio_tests/tests/qps/benchmark_server.py
index bb07844..2bd89cb 100644
--- a/src/python/grpcio_tests/tests/qps/benchmark_server.py
+++ b/src/python/grpcio_tests/tests/qps/benchmark_server.py
@@ -13,10 +13,10 @@
# limitations under the License.
from src.proto.grpc.testing import messages_pb2
-from src.proto.grpc.testing import services_pb2_grpc
+from src.proto.grpc.testing import benchmark_service_pb2_grpc
-class BenchmarkServer(services_pb2_grpc.BenchmarkServiceServicer):
+class BenchmarkServer(benchmark_service_pb2_grpc.BenchmarkServiceServicer):
"""Synchronous Server implementation for the Benchmark service."""
def UnaryCall(self, request, context):
@@ -29,7 +29,8 @@
yield messages_pb2.SimpleResponse(payload=payload)
-class GenericBenchmarkServer(services_pb2_grpc.BenchmarkServiceServicer):
+class GenericBenchmarkServer(
+ benchmark_service_pb2_grpc.BenchmarkServiceServicer):
"""Generic Server implementation for the Benchmark service."""
def __init__(self, resp_size):
diff --git a/src/python/grpcio_tests/tests/qps/qps_worker.py b/src/python/grpcio_tests/tests/qps/qps_worker.py
index 54f69db..c33d013 100644
--- a/src/python/grpcio_tests/tests/qps/qps_worker.py
+++ b/src/python/grpcio_tests/tests/qps/qps_worker.py
@@ -17,7 +17,7 @@
import time
import grpc
-from src.proto.grpc.testing import services_pb2_grpc
+from src.proto.grpc.testing import worker_service_pb2_grpc
from tests.qps import worker_server
from tests.unit import test_common
@@ -26,7 +26,8 @@
def run_worker_server(port):
server = test_common.test_server()
servicer = worker_server.WorkerServer()
- services_pb2_grpc.add_WorkerServiceServicer_to_server(servicer, server)
+ worker_service_pb2_grpc.add_WorkerServiceServicer_to_server(
+ servicer, server)
server.add_insecure_port('[::]:{}'.format(port))
server.start()
servicer.wait_for_quit()
diff --git a/src/python/grpcio_tests/tests/qps/worker_server.py b/src/python/grpcio_tests/tests/qps/worker_server.py
index 41e2403..db145fb 100644
--- a/src/python/grpcio_tests/tests/qps/worker_server.py
+++ b/src/python/grpcio_tests/tests/qps/worker_server.py
@@ -20,7 +20,7 @@
from concurrent import futures
import grpc
from src.proto.grpc.testing import control_pb2
-from src.proto.grpc.testing import services_pb2_grpc
+from src.proto.grpc.testing import worker_service_pb2_grpc
from src.proto.grpc.testing import stats_pb2
from tests.qps import benchmark_client
@@ -31,7 +31,7 @@
from tests.unit import test_common
-class WorkerServer(services_pb2_grpc.WorkerServiceServicer):
+class WorkerServer(worker_service_pb2_grpc.WorkerServiceServicer):
"""Python Worker Server implementation."""
def __init__(self):
@@ -72,7 +72,7 @@
server = test_common.test_server(max_workers=server_threads)
if config.server_type == control_pb2.ASYNC_SERVER:
servicer = benchmark_server.BenchmarkServer()
- services_pb2_grpc.add_BenchmarkServiceServicer_to_server(
+ worker_service_pb2_grpc.add_BenchmarkServiceServicer_to_server(
servicer, server)
elif config.server_type == control_pb2.ASYNC_GENERIC_SERVER:
resp_size = config.payload_config.bytebuf_params.resp_size
diff --git a/src/python/grpcio_tests/tests/stress/test_runner.py b/src/python/grpcio_tests/tests/stress/test_runner.py
index d5038e3..764cda1 100644
--- a/src/python/grpcio_tests/tests/stress/test_runner.py
+++ b/src/python/grpcio_tests/tests/stress/test_runner.py
@@ -50,7 +50,7 @@
test_case.test_interoperability(self._stub, None)
end_time = time.time()
self._histogram.add((end_time - start_time) * 1e9)
- except Exception as e:
+ except Exception as e: # pylint: disable=broad-except
traceback.print_exc()
self._exception_queue.put(
Exception("An exception occured during test {}"
diff --git a/src/python/grpcio_tests/tests/testing/_client_application.py b/src/python/grpcio_tests/tests/testing/_client_application.py
index 7d0d74c..3ddeba2 100644
--- a/src/python/grpcio_tests/tests/testing/_client_application.py
+++ b/src/python/grpcio_tests/tests/testing/_client_application.py
@@ -215,30 +215,6 @@
return _UNSATISFACTORY_OUTCOME
-def run(scenario, channel):
- stub = services_pb2_grpc.FirstServiceStub(channel)
- try:
- if scenario is Scenario.UNARY_UNARY:
- return _run_unary_unary(stub)
- elif scenario is Scenario.UNARY_STREAM:
- return _run_unary_stream(stub)
- elif scenario is Scenario.STREAM_UNARY:
- return _run_stream_unary(stub)
- elif scenario is Scenario.STREAM_STREAM:
- return _run_stream_stream(stub)
- elif scenario is Scenario.CONCURRENT_STREAM_UNARY:
- return _run_concurrent_stream_unary(stub)
- elif scenario is Scenario.CONCURRENT_STREAM_STREAM:
- return _run_concurrent_stream_stream(stub)
- elif scenario is Scenario.CANCEL_UNARY_UNARY:
- return _run_cancel_unary_unary(stub)
- elif scenario is Scenario.INFINITE_REQUEST_STREAM:
- return _run_infinite_request_stream(stub)
- except grpc.RpcError as rpc_error:
- return Outcome(Outcome.Kind.RPC_ERROR, rpc_error.code(),
- rpc_error.details())
-
-
_IMPLEMENTATIONS = {
Scenario.UNARY_UNARY: _run_unary_unary,
Scenario.UNARY_STREAM: _run_unary_stream,
diff --git a/src/python/grpcio_tests/tests/testing/_server_application.py b/src/python/grpcio_tests/tests/testing/_server_application.py
index 02769ca..243c385 100644
--- a/src/python/grpcio_tests/tests/testing/_server_application.py
+++ b/src/python/grpcio_tests/tests/testing/_server_application.py
@@ -38,7 +38,7 @@
context.set_code(grpc.StatusCode.INVALID_ARGUMENT)
context.set_details('Something is wrong with your request!')
return
- yield services_pb2.Strange()
+ yield services_pb2.Strange() # pylint: disable=unreachable
def StreUn(self, request_iterator, context):
context.send_initial_metadata(((
diff --git a/src/python/grpcio_tests/tests/testing/_server_test.py b/src/python/grpcio_tests/tests/testing/_server_test.py
index 4f4abd7..88e3a79 100644
--- a/src/python/grpcio_tests/tests/testing/_server_test.py
+++ b/src/python/grpcio_tests/tests/testing/_server_test.py
@@ -21,13 +21,8 @@
from tests.testing import _application_common
from tests.testing import _application_testing_common
from tests.testing import _server_application
-from tests.testing.proto import services_pb2
-# TODO(https://github.com/google/protobuf/issues/3452): Drop this skip.
-@unittest.skipIf(
- services_pb2.DESCRIPTOR.services_by_name.get('FirstService') is None,
- 'Fix protobuf issue 3452!')
class FirstServiceServicerTest(unittest.TestCase):
def setUp(self):
diff --git a/src/python/grpcio_tests/tests/tests.json b/src/python/grpcio_tests/tests/tests.json
index d38ee51..0d94426 100644
--- a/src/python/grpcio_tests/tests/tests.json
+++ b/src/python/grpcio_tests/tests/tests.json
@@ -25,6 +25,7 @@
"unit._auth_test.AccessTokenAuthMetadataPluginTest",
"unit._auth_test.GoogleCallCredentialsTest",
"unit._channel_args_test.ChannelArgsTest",
+ "unit._channel_close_test.ChannelCloseTest",
"unit._channel_connectivity_test.ChannelConnectivityTest",
"unit._channel_ready_future_test.ChannelReadyFutureTest",
"unit._compression_test.CompressionTest",
@@ -52,7 +53,6 @@
"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",
"unit.beta._connectivity_channel_test.ConnectivityStatesTest",
diff --git a/src/python/grpcio_tests/tests/unit/_channel_close_test.py b/src/python/grpcio_tests/tests/unit/_channel_close_test.py
new file mode 100644
index 0000000..af3a9ee
--- /dev/null
+++ b/src/python/grpcio_tests/tests/unit/_channel_close_test.py
@@ -0,0 +1,185 @@
+# Copyright 2018 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 and client side compression."""
+
+import threading
+import time
+import unittest
+
+import grpc
+
+from tests.unit import test_common
+from tests.unit.framework.common import test_constants
+
+_BEAT = 0.5
+_SOME_TIME = 5
+_MORE_TIME = 10
+
+
+class _MethodHandler(grpc.RpcMethodHandler):
+
+ request_streaming = True
+ response_streaming = True
+ request_deserializer = None
+ response_serializer = None
+
+ def stream_stream(self, request_iterator, servicer_context):
+ for request in request_iterator:
+ yield request * 2
+
+
+_METHOD_HANDLER = _MethodHandler()
+
+
+class _GenericHandler(grpc.GenericRpcHandler):
+
+ def service(self, handler_call_details):
+ return _METHOD_HANDLER
+
+
+_GENERIC_HANDLER = _GenericHandler()
+
+
+class _Pipe(object):
+
+ def __init__(self, values):
+ self._condition = threading.Condition()
+ self._values = list(values)
+ self._open = True
+
+ def __iter__(self):
+ return self
+
+ def _next(self):
+ with self._condition:
+ while not self._values and self._open:
+ self._condition.wait()
+ if self._values:
+ return self._values.pop(0)
+ else:
+ raise StopIteration()
+
+ def next(self):
+ return self._next()
+
+ def __next__(self):
+ return self._next()
+
+ def add(self, value):
+ with self._condition:
+ self._values.append(value)
+ self._condition.notify()
+
+ def close(self):
+ with self._condition:
+ self._open = False
+ self._condition.notify()
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, type, value, traceback):
+ self.close()
+
+
+class ChannelCloseTest(unittest.TestCase):
+
+ def setUp(self):
+ self._server = test_common.test_server(
+ max_workers=test_constants.THREAD_CONCURRENCY)
+ self._server.add_generic_rpc_handlers((_GENERIC_HANDLER,))
+ self._port = self._server.add_insecure_port('[::]:0')
+ self._server.start()
+
+ def tearDown(self):
+ self._server.stop(None)
+
+ def test_close_immediately_after_call_invocation(self):
+ channel = grpc.insecure_channel('localhost:{}'.format(self._port))
+ multi_callable = channel.stream_stream('Meffod')
+ request_iterator = _Pipe(())
+ response_iterator = multi_callable(request_iterator)
+ channel.close()
+ request_iterator.close()
+
+ self.assertIs(response_iterator.code(), grpc.StatusCode.CANCELLED)
+
+ def test_close_while_call_active(self):
+ channel = grpc.insecure_channel('localhost:{}'.format(self._port))
+ multi_callable = channel.stream_stream('Meffod')
+ request_iterator = _Pipe((b'abc',))
+ response_iterator = multi_callable(request_iterator)
+ next(response_iterator)
+ channel.close()
+ request_iterator.close()
+
+ self.assertIs(response_iterator.code(), grpc.StatusCode.CANCELLED)
+
+ def test_context_manager_close_while_call_active(self):
+ with grpc.insecure_channel('localhost:{}'.format(
+ self._port)) as channel: # pylint: disable=bad-continuation
+ multi_callable = channel.stream_stream('Meffod')
+ request_iterator = _Pipe((b'abc',))
+ response_iterator = multi_callable(request_iterator)
+ next(response_iterator)
+ request_iterator.close()
+
+ self.assertIs(response_iterator.code(), grpc.StatusCode.CANCELLED)
+
+ def test_context_manager_close_while_many_calls_active(self):
+ with grpc.insecure_channel('localhost:{}'.format(
+ self._port)) as channel: # pylint: disable=bad-continuation
+ multi_callable = channel.stream_stream('Meffod')
+ request_iterators = tuple(
+ _Pipe((b'abc',))
+ for _ in range(test_constants.THREAD_CONCURRENCY))
+ response_iterators = []
+ for request_iterator in request_iterators:
+ response_iterator = multi_callable(request_iterator)
+ next(response_iterator)
+ response_iterators.append(response_iterator)
+ for request_iterator in request_iterators:
+ request_iterator.close()
+
+ for response_iterator in response_iterators:
+ self.assertIs(response_iterator.code(), grpc.StatusCode.CANCELLED)
+
+ def test_many_concurrent_closes(self):
+ channel = grpc.insecure_channel('localhost:{}'.format(self._port))
+ multi_callable = channel.stream_stream('Meffod')
+ request_iterator = _Pipe((b'abc',))
+ response_iterator = multi_callable(request_iterator)
+ next(response_iterator)
+ start = time.time()
+ end = start + _MORE_TIME
+
+ def sleep_some_time_then_close():
+ time.sleep(_SOME_TIME)
+ channel.close()
+
+ for _ in range(test_constants.THREAD_CONCURRENCY):
+ close_thread = threading.Thread(target=sleep_some_time_then_close)
+ close_thread.start()
+ while True:
+ request_iterator.add(b'def')
+ time.sleep(_BEAT)
+ if end < time.time():
+ break
+ request_iterator.close()
+
+ self.assertIs(response_iterator.code(), grpc.StatusCode.CANCELLED)
+
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_compression_test.py b/src/python/grpcio_tests/tests/unit/_compression_test.py
index 7550cd3..0b11f03 100644
--- a/src/python/grpcio_tests/tests/unit/_compression_test.py
+++ b/src/python/grpcio_tests/tests/unit/_compression_test.py
@@ -52,9 +52,9 @@
self.stream_unary = None
self.stream_stream = None
if self.request_streaming and self.response_streaming:
- self.stream_stream = lambda x, y: handle_stream(x, y)
+ self.stream_stream = handle_stream
elif not self.request_streaming and not self.response_streaming:
- self.unary_unary = lambda x, y: handle_unary(x, y)
+ self.unary_unary = handle_unary
class _GenericHandler(grpc.GenericRpcHandler):
diff --git a/src/python/grpcio_tests/tests/unit/_cython/_cancel_many_calls_test.py b/src/python/grpcio_tests/tests/unit/_cython/_cancel_many_calls_test.py
index 3765ce4..578a3d7 100644
--- a/src/python/grpcio_tests/tests/unit/_cython/_cancel_many_calls_test.py
+++ b/src/python/grpcio_tests/tests/unit/_cython/_cancel_many_calls_test.py
@@ -19,6 +19,7 @@
from grpc._cython import cygrpc
from grpc.framework.foundation import logging_pool
from tests.unit.framework.common import test_constants
+from tests.unit._cython import test_utilities
_EMPTY_FLAGS = 0
_EMPTY_METADATA = ()
@@ -30,6 +31,8 @@
_SERVER_COMPLETE_CALL_TAG = 'server_complete_call'
_SUCCESS_CALL_FRACTION = 1.0 / 8.0
+_SUCCESSFUL_CALLS = int(test_constants.RPC_CONCURRENCY * _SUCCESS_CALL_FRACTION)
+_UNSUCCESSFUL_CALLS = test_constants.RPC_CONCURRENCY - _SUCCESSFUL_CALLS
class _State(object):
@@ -43,7 +46,7 @@
def _is_cancellation_event(event):
return (event.tag is _RECEIVE_CLOSE_ON_SERVER_TAG and
- event.batch_operations[0].received_cancelled)
+ event.batch_operations[0].cancelled())
class _Handler(object):
@@ -150,7 +153,8 @@
server.register_completion_queue(server_completion_queue)
port = server.add_http2_port(b'[::]:0')
server.start()
- channel = cygrpc.Channel('localhost:{}'.format(port).encode(), None)
+ channel = cygrpc.Channel('localhost:{}'.format(port).encode(), None,
+ None)
state = _State()
@@ -165,31 +169,33 @@
client_condition = threading.Condition()
client_due = set()
- client_completion_queue = cygrpc.CompletionQueue()
- client_driver = _QueueDriver(client_condition, client_completion_queue,
- client_due)
- client_driver.start()
with client_condition:
client_calls = []
for index in range(test_constants.RPC_CONCURRENCY):
- client_call = channel.create_call(None, _EMPTY_FLAGS,
- client_completion_queue,
- b'/twinkies', None, None)
- operations = (
- cygrpc.SendInitialMetadataOperation(_EMPTY_METADATA,
- _EMPTY_FLAGS),
- cygrpc.SendMessageOperation(b'\x45\x56', _EMPTY_FLAGS),
- cygrpc.SendCloseFromClientOperation(_EMPTY_FLAGS),
- cygrpc.ReceiveInitialMetadataOperation(_EMPTY_FLAGS),
- cygrpc.ReceiveMessageOperation(_EMPTY_FLAGS),
- cygrpc.ReceiveStatusOnClientOperation(_EMPTY_FLAGS),
- )
tag = 'client_complete_call_{0:04d}_tag'.format(index)
- client_call.start_client_batch(operations, tag)
+ client_call = channel.integrated_call(
+ _EMPTY_FLAGS, b'/twinkies', None, None, _EMPTY_METADATA,
+ None, ((
+ (
+ cygrpc.SendInitialMetadataOperation(
+ _EMPTY_METADATA, _EMPTY_FLAGS),
+ cygrpc.SendMessageOperation(b'\x45\x56',
+ _EMPTY_FLAGS),
+ cygrpc.SendCloseFromClientOperation(_EMPTY_FLAGS),
+ cygrpc.ReceiveInitialMetadataOperation(
+ _EMPTY_FLAGS),
+ cygrpc.ReceiveMessageOperation(_EMPTY_FLAGS),
+ cygrpc.ReceiveStatusOnClientOperation(_EMPTY_FLAGS),
+ ),
+ tag,
+ ),))
client_due.add(tag)
client_calls.append(client_call)
+ client_events_future = test_utilities.SimpleFuture(
+ lambda: tuple(channel.next_call_event() for _ in range(_SUCCESSFUL_CALLS)))
+
with state.condition:
while True:
if state.parked_handlers < test_constants.THREAD_CONCURRENCY:
@@ -201,12 +207,14 @@
state.condition.notify_all()
break
- client_driver.events(
- test_constants.RPC_CONCURRENCY * _SUCCESS_CALL_FRACTION)
+ client_events_future.result()
with client_condition:
for client_call in client_calls:
- client_call.cancel()
+ client_call.cancel(cygrpc.StatusCode.cancelled, 'Cancelled!')
+ for _ in range(_UNSUCCESSFUL_CALLS):
+ channel.next_call_event()
+ channel.close(cygrpc.StatusCode.unknown, 'Cancelled on channel close!')
with state.condition:
server.shutdown(server_completion_queue, _SERVER_SHUTDOWN_TAG)
diff --git a/src/python/grpcio_tests/tests/unit/_cython/_channel_test.py b/src/python/grpcio_tests/tests/unit/_cython/_channel_test.py
index 7305d0f..d952860 100644
--- a/src/python/grpcio_tests/tests/unit/_cython/_channel_test.py
+++ b/src/python/grpcio_tests/tests/unit/_cython/_channel_test.py
@@ -21,25 +21,20 @@
from tests.unit.framework.common import test_constants
-def _channel_and_completion_queue():
- channel = cygrpc.Channel(b'localhost:54321', ())
- completion_queue = cygrpc.CompletionQueue()
- return channel, completion_queue
+def _channel():
+ return cygrpc.Channel(b'localhost:54321', (), None)
-def _connectivity_loop(channel, completion_queue):
+def _connectivity_loop(channel):
for _ in range(100):
connectivity = channel.check_connectivity_state(True)
- channel.watch_connectivity_state(connectivity,
- time.time() + 0.2, completion_queue,
- None)
- completion_queue.poll()
+ channel.watch_connectivity_state(connectivity, time.time() + 0.2)
def _create_loop_destroy():
- channel, completion_queue = _channel_and_completion_queue()
- _connectivity_loop(channel, completion_queue)
- completion_queue.shutdown()
+ channel = _channel()
+ _connectivity_loop(channel)
+ channel.close(cygrpc.StatusCode.ok, 'Channel close!')
def _in_parallel(behavior, arguments):
@@ -55,12 +50,9 @@
class ChannelTest(unittest.TestCase):
def test_single_channel_lonely_connectivity(self):
- channel, completion_queue = _channel_and_completion_queue()
- _in_parallel(_connectivity_loop, (
- channel,
- completion_queue,
- ))
- completion_queue.shutdown()
+ channel = _channel()
+ _connectivity_loop(channel)
+ channel.close(cygrpc.StatusCode.ok, 'Channel close!')
def test_multiple_channels_lonely_connectivity(self):
_in_parallel(_create_loop_destroy, ())
diff --git a/src/python/grpcio_tests/tests/unit/_cython/_common.py b/src/python/grpcio_tests/tests/unit/_cython/_common.py
index 7fd3d19..d8210f3 100644
--- a/src/python/grpcio_tests/tests/unit/_cython/_common.py
+++ b/src/python/grpcio_tests/tests/unit/_cython/_common.py
@@ -100,7 +100,8 @@
self.server.register_completion_queue(self.server_completion_queue)
port = self.server.add_http2_port(b'[::]:0')
self.server.start()
- self.channel = cygrpc.Channel('localhost:{}'.format(port).encode(), [])
+ self.channel = cygrpc.Channel('localhost:{}'.format(port).encode(), [],
+ None)
self._server_shutdown_tag = 'server_shutdown_tag'
self.server_condition = threading.Condition()
diff --git a/src/python/grpcio_tests/tests/unit/_cython/_no_messages_server_completion_queue_per_call_test.py b/src/python/grpcio_tests/tests/unit/_cython/_no_messages_server_completion_queue_per_call_test.py
index 7caa98f..8a72178 100644
--- a/src/python/grpcio_tests/tests/unit/_cython/_no_messages_server_completion_queue_per_call_test.py
+++ b/src/python/grpcio_tests/tests/unit/_cython/_no_messages_server_completion_queue_per_call_test.py
@@ -19,6 +19,7 @@
from grpc._cython import cygrpc
from tests.unit._cython import _common
+from tests.unit._cython import test_utilities
class Test(_common.RpcTest, unittest.TestCase):
@@ -41,31 +42,27 @@
server_request_call_tag,
})
- client_call = self.channel.create_call(None, _common.EMPTY_FLAGS,
- self.client_completion_queue,
- b'/twinkies', None, None)
client_receive_initial_metadata_tag = 'client_receive_initial_metadata_tag'
client_complete_rpc_tag = 'client_complete_rpc_tag'
- with self.client_condition:
- client_receive_initial_metadata_start_batch_result = (
- client_call.start_client_batch([
- cygrpc.ReceiveInitialMetadataOperation(_common.EMPTY_FLAGS),
- ], client_receive_initial_metadata_tag))
- self.assertEqual(cygrpc.CallError.ok,
- client_receive_initial_metadata_start_batch_result)
- client_complete_rpc_start_batch_result = client_call.start_client_batch(
+ client_call = self.channel.integrated_call(
+ _common.EMPTY_FLAGS, b'/twinkies', None, None,
+ _common.INVOCATION_METADATA, None, [(
[
- cygrpc.SendInitialMetadataOperation(
- _common.INVOCATION_METADATA, _common.EMPTY_FLAGS),
- cygrpc.SendCloseFromClientOperation(_common.EMPTY_FLAGS),
- cygrpc.ReceiveStatusOnClientOperation(_common.EMPTY_FLAGS),
- ], client_complete_rpc_tag)
- self.assertEqual(cygrpc.CallError.ok,
- client_complete_rpc_start_batch_result)
- self.client_driver.add_due({
+ cygrpc.ReceiveInitialMetadataOperation(_common.EMPTY_FLAGS),
+ ],
client_receive_initial_metadata_tag,
- client_complete_rpc_tag,
- })
+ )])
+ client_call.operate([
+ cygrpc.SendInitialMetadataOperation(_common.INVOCATION_METADATA,
+ _common.EMPTY_FLAGS),
+ cygrpc.SendCloseFromClientOperation(_common.EMPTY_FLAGS),
+ cygrpc.ReceiveStatusOnClientOperation(_common.EMPTY_FLAGS),
+ ], client_complete_rpc_tag)
+
+ client_events_future = test_utilities.SimpleFuture(
+ lambda: [
+ self.channel.next_call_event(),
+ self.channel.next_call_event(),])
server_request_call_event = self.server_driver.event_with_tag(
server_request_call_tag)
@@ -96,20 +93,23 @@
server_complete_rpc_event = server_call_driver.event_with_tag(
server_complete_rpc_tag)
- client_receive_initial_metadata_event = self.client_driver.event_with_tag(
- client_receive_initial_metadata_tag)
- client_complete_rpc_event = self.client_driver.event_with_tag(
- client_complete_rpc_tag)
+ client_events = client_events_future.result()
+ if client_events[0].tag is client_receive_initial_metadata_tag:
+ client_receive_initial_metadata_event = client_events[0]
+ client_complete_rpc_event = client_events[1]
+ else:
+ client_complete_rpc_event = client_events[0]
+ client_receive_initial_metadata_event = client_events[1]
return (
_common.OperationResult(server_request_call_start_batch_result,
server_request_call_event.completion_type,
server_request_call_event.success),
_common.OperationResult(
- client_receive_initial_metadata_start_batch_result,
+ cygrpc.CallError.ok,
client_receive_initial_metadata_event.completion_type,
client_receive_initial_metadata_event.success),
- _common.OperationResult(client_complete_rpc_start_batch_result,
+ _common.OperationResult(cygrpc.CallError.ok,
client_complete_rpc_event.completion_type,
client_complete_rpc_event.success),
_common.OperationResult(
diff --git a/src/python/grpcio_tests/tests/unit/_cython/_no_messages_single_server_completion_queue_test.py b/src/python/grpcio_tests/tests/unit/_cython/_no_messages_single_server_completion_queue_test.py
index 8582a39..47f39eb 100644
--- a/src/python/grpcio_tests/tests/unit/_cython/_no_messages_single_server_completion_queue_test.py
+++ b/src/python/grpcio_tests/tests/unit/_cython/_no_messages_single_server_completion_queue_test.py
@@ -19,6 +19,7 @@
from grpc._cython import cygrpc
from tests.unit._cython import _common
+from tests.unit._cython import test_utilities
class Test(_common.RpcTest, unittest.TestCase):
@@ -36,28 +37,31 @@
server_request_call_tag,
})
- client_call = self.channel.create_call(None, _common.EMPTY_FLAGS,
- self.client_completion_queue,
- b'/twinkies', None, None)
client_receive_initial_metadata_tag = 'client_receive_initial_metadata_tag'
client_complete_rpc_tag = 'client_complete_rpc_tag'
- with self.client_condition:
- client_receive_initial_metadata_start_batch_result = (
- client_call.start_client_batch([
- cygrpc.ReceiveInitialMetadataOperation(_common.EMPTY_FLAGS),
- ], client_receive_initial_metadata_tag))
- client_complete_rpc_start_batch_result = client_call.start_client_batch(
- [
- cygrpc.SendInitialMetadataOperation(
- _common.INVOCATION_METADATA, _common.EMPTY_FLAGS),
- cygrpc.SendCloseFromClientOperation(_common.EMPTY_FLAGS),
- cygrpc.ReceiveStatusOnClientOperation(_common.EMPTY_FLAGS),
- ], client_complete_rpc_tag)
- self.client_driver.add_due({
- client_receive_initial_metadata_tag,
- client_complete_rpc_tag,
- })
+ client_call = self.channel.integrated_call(
+ _common.EMPTY_FLAGS, b'/twinkies', None, None,
+ _common.INVOCATION_METADATA, None, [
+ (
+ [
+ cygrpc.SendInitialMetadataOperation(
+ _common.INVOCATION_METADATA, _common.EMPTY_FLAGS),
+ cygrpc.SendCloseFromClientOperation(
+ _common.EMPTY_FLAGS),
+ cygrpc.ReceiveStatusOnClientOperation(
+ _common.EMPTY_FLAGS),
+ ],
+ client_complete_rpc_tag,
+ ),
+ ])
+ client_call.operate([
+ cygrpc.ReceiveInitialMetadataOperation(_common.EMPTY_FLAGS),
+ ], client_receive_initial_metadata_tag)
+ client_events_future = test_utilities.SimpleFuture(
+ lambda: [
+ self.channel.next_call_event(),
+ self.channel.next_call_event(),])
server_request_call_event = self.server_driver.event_with_tag(
server_request_call_tag)
@@ -87,20 +91,19 @@
server_complete_rpc_event = self.server_driver.event_with_tag(
server_complete_rpc_tag)
- client_receive_initial_metadata_event = self.client_driver.event_with_tag(
- client_receive_initial_metadata_tag)
- client_complete_rpc_event = self.client_driver.event_with_tag(
- client_complete_rpc_tag)
+ client_events = client_events_future.result()
+ client_receive_initial_metadata_event = client_events[0]
+ client_complete_rpc_event = client_events[1]
return (
_common.OperationResult(server_request_call_start_batch_result,
server_request_call_event.completion_type,
server_request_call_event.success),
_common.OperationResult(
- client_receive_initial_metadata_start_batch_result,
+ cygrpc.CallError.ok,
client_receive_initial_metadata_event.completion_type,
client_receive_initial_metadata_event.success),
- _common.OperationResult(client_complete_rpc_start_batch_result,
+ _common.OperationResult(cygrpc.CallError.ok,
client_complete_rpc_event.completion_type,
client_complete_rpc_event.success),
_common.OperationResult(
diff --git a/src/python/grpcio_tests/tests/unit/_cython/_read_some_but_not_all_responses_test.py b/src/python/grpcio_tests/tests/unit/_cython/_read_some_but_not_all_responses_test.py
index bc63b54..8a903bf 100644
--- a/src/python/grpcio_tests/tests/unit/_cython/_read_some_but_not_all_responses_test.py
+++ b/src/python/grpcio_tests/tests/unit/_cython/_read_some_but_not_all_responses_test.py
@@ -17,6 +17,7 @@
import unittest
from grpc._cython import cygrpc
+from tests.unit._cython import test_utilities
_EMPTY_FLAGS = 0
_EMPTY_METADATA = ()
@@ -118,7 +119,8 @@
server.register_completion_queue(server_completion_queue)
port = server.add_http2_port(b'[::]:0')
server.start()
- channel = cygrpc.Channel('localhost:{}'.format(port).encode(), set())
+ channel = cygrpc.Channel('localhost:{}'.format(port).encode(), set(),
+ None)
server_shutdown_tag = 'server_shutdown_tag'
server_driver = _ServerDriver(server_completion_queue,
@@ -127,10 +129,6 @@
client_condition = threading.Condition()
client_due = set()
- client_completion_queue = cygrpc.CompletionQueue()
- client_driver = _QueueDriver(client_condition, client_completion_queue,
- client_due)
- client_driver.start()
server_call_condition = threading.Condition()
server_send_initial_metadata_tag = 'server_send_initial_metadata_tag'
@@ -154,25 +152,28 @@
server_completion_queue,
server_rpc_tag)
- client_call = channel.create_call(None, _EMPTY_FLAGS,
- client_completion_queue, b'/twinkies',
- None, None)
client_receive_initial_metadata_tag = 'client_receive_initial_metadata_tag'
client_complete_rpc_tag = 'client_complete_rpc_tag'
- with client_condition:
- client_receive_initial_metadata_start_batch_result = (
- client_call.start_client_batch([
- cygrpc.ReceiveInitialMetadataOperation(_EMPTY_FLAGS),
- ], client_receive_initial_metadata_tag))
- client_due.add(client_receive_initial_metadata_tag)
- client_complete_rpc_start_batch_result = (
- client_call.start_client_batch([
- cygrpc.SendInitialMetadataOperation(_EMPTY_METADATA,
- _EMPTY_FLAGS),
- cygrpc.SendCloseFromClientOperation(_EMPTY_FLAGS),
- cygrpc.ReceiveStatusOnClientOperation(_EMPTY_FLAGS),
- ], client_complete_rpc_tag))
- client_due.add(client_complete_rpc_tag)
+ client_call = channel.segregated_call(
+ _EMPTY_FLAGS, b'/twinkies', None, None, _EMPTY_METADATA, None, (
+ (
+ [
+ cygrpc.ReceiveInitialMetadataOperation(_EMPTY_FLAGS),
+ ],
+ client_receive_initial_metadata_tag,
+ ),
+ (
+ [
+ cygrpc.SendInitialMetadataOperation(
+ _EMPTY_METADATA, _EMPTY_FLAGS),
+ cygrpc.SendCloseFromClientOperation(_EMPTY_FLAGS),
+ cygrpc.ReceiveStatusOnClientOperation(_EMPTY_FLAGS),
+ ],
+ client_complete_rpc_tag,
+ ),
+ ))
+ client_receive_initial_metadata_event_future = test_utilities.SimpleFuture(
+ client_call.next_event)
server_rpc_event = server_driver.first_event()
@@ -208,19 +209,20 @@
server_complete_rpc_tag)
server_call_driver.events()
- with client_condition:
- client_receive_first_message_tag = 'client_receive_first_message_tag'
- client_receive_first_message_start_batch_result = (
- client_call.start_client_batch([
- cygrpc.ReceiveMessageOperation(_EMPTY_FLAGS),
- ], client_receive_first_message_tag))
- client_due.add(client_receive_first_message_tag)
- client_receive_first_message_event = client_driver.event_with_tag(
- client_receive_first_message_tag)
+ client_recieve_initial_metadata_event = client_receive_initial_metadata_event_future.result(
+ )
- client_call_cancel_result = client_call.cancel()
- client_driver.events()
+ client_receive_first_message_tag = 'client_receive_first_message_tag'
+ client_call.operate([
+ cygrpc.ReceiveMessageOperation(_EMPTY_FLAGS),
+ ], client_receive_first_message_tag)
+ client_receive_first_message_event = client_call.next_event()
+ client_call_cancel_result = client_call.cancel(
+ cygrpc.StatusCode.cancelled, 'Cancelled during test!')
+ client_complete_rpc_event = client_call.next_event()
+
+ channel.close(cygrpc.StatusCode.unknown, 'Channel closed!')
server.shutdown(server_completion_queue, server_shutdown_tag)
server.cancel_all_calls()
server_driver.events()
@@ -228,11 +230,6 @@
self.assertEqual(cygrpc.CallError.ok, request_call_result)
self.assertEqual(cygrpc.CallError.ok,
server_send_initial_metadata_start_batch_result)
- self.assertEqual(cygrpc.CallError.ok,
- client_receive_initial_metadata_start_batch_result)
- self.assertEqual(cygrpc.CallError.ok,
- client_complete_rpc_start_batch_result)
- self.assertEqual(cygrpc.CallError.ok, client_call_cancel_result)
self.assertIs(server_rpc_tag, server_rpc_event.tag)
self.assertEqual(cygrpc.CompletionType.operation_complete,
server_rpc_event.completion_type)
diff --git a/src/python/grpcio_tests/tests/unit/_cython/cygrpc_test.py b/src/python/grpcio_tests/tests/unit/_cython/cygrpc_test.py
index 9045ff5..724a690 100644
--- a/src/python/grpcio_tests/tests/unit/_cython/cygrpc_test.py
+++ b/src/python/grpcio_tests/tests/unit/_cython/cygrpc_test.py
@@ -51,8 +51,8 @@
del server
def testChannelUpDown(self):
- channel = cygrpc.Channel(b'[::]:0', None)
- del channel
+ channel = cygrpc.Channel(b'[::]:0', None, None)
+ channel.close(cygrpc.StatusCode.cancelled, 'Test method anyway!')
def test_metadata_plugin_call_credentials_up_down(self):
cygrpc.MetadataPluginCallCredentials(_metadata_plugin,
@@ -121,7 +121,7 @@
client_credentials)
else:
self.client_channel = cygrpc.Channel('localhost:{}'.format(
- self.port).encode(), set())
+ self.port).encode(), set(), None)
if host_override:
self.host_argument = None # default host
self.expected_host = host_override
@@ -131,17 +131,20 @@
self.expected_host = self.host_argument
def tearDownMixin(self):
+ self.client_channel.close(cygrpc.StatusCode.ok, 'test being torn down!')
+ del self.client_channel
del self.server
del self.client_completion_queue
del self.server_completion_queue
- def _perform_operations(self, operations, call, queue, deadline,
- description):
- """Perform the list of operations with given call, queue, and deadline.
+ def _perform_queue_operations(self, operations, call, queue, deadline,
+ description):
+ """Perform the operations with given call, queue, and deadline.
- Invocation errors are reported with as an exception with `description` in
- the message. Performs the operations asynchronously, returning a future.
- """
+ Invocation errors are reported with as an exception with `description`
+ in the message. Performs the operations asynchronously, returning a
+ future.
+ """
def performer():
tag = object()
@@ -185,9 +188,6 @@
self.assertEqual(cygrpc.CallError.ok, request_call_result)
client_call_tag = object()
- client_call = self.client_channel.create_call(
- None, 0, self.client_completion_queue, METHOD, self.host_argument,
- DEADLINE)
client_initial_metadata = (
(
CLIENT_METADATA_ASCII_KEY,
@@ -198,18 +198,24 @@
CLIENT_METADATA_BIN_VALUE,
),
)
- client_start_batch_result = client_call.start_client_batch([
- cygrpc.SendInitialMetadataOperation(client_initial_metadata,
- _EMPTY_FLAGS),
- cygrpc.SendMessageOperation(REQUEST, _EMPTY_FLAGS),
- cygrpc.SendCloseFromClientOperation(_EMPTY_FLAGS),
- cygrpc.ReceiveInitialMetadataOperation(_EMPTY_FLAGS),
- cygrpc.ReceiveMessageOperation(_EMPTY_FLAGS),
- cygrpc.ReceiveStatusOnClientOperation(_EMPTY_FLAGS),
- ], client_call_tag)
- self.assertEqual(cygrpc.CallError.ok, client_start_batch_result)
- client_event_future = test_utilities.CompletionQueuePollFuture(
- self.client_completion_queue, DEADLINE)
+ client_call = self.client_channel.integrated_call(
+ 0, METHOD, self.host_argument, DEADLINE, client_initial_metadata,
+ None, [
+ (
+ [
+ cygrpc.SendInitialMetadataOperation(
+ client_initial_metadata, _EMPTY_FLAGS),
+ cygrpc.SendMessageOperation(REQUEST, _EMPTY_FLAGS),
+ cygrpc.SendCloseFromClientOperation(_EMPTY_FLAGS),
+ cygrpc.ReceiveInitialMetadataOperation(_EMPTY_FLAGS),
+ cygrpc.ReceiveMessageOperation(_EMPTY_FLAGS),
+ cygrpc.ReceiveStatusOnClientOperation(_EMPTY_FLAGS),
+ ],
+ client_call_tag,
+ ),
+ ])
+ client_event_future = test_utilities.SimpleFuture(
+ self.client_channel.next_call_event)
request_event = self.server_completion_queue.poll(deadline=DEADLINE)
self.assertEqual(cygrpc.CompletionType.operation_complete,
@@ -285,7 +291,7 @@
self.assertEqual(5, len(server_event.batch_operations))
found_server_op_types = set()
for server_result in server_event.batch_operations:
- self.assertNotIn(client_result.type(), found_server_op_types)
+ self.assertNotIn(server_result.type(), found_server_op_types)
found_server_op_types.add(server_result.type())
if server_result.type() == cygrpc.OperationType.receive_message:
self.assertEqual(REQUEST, server_result.message())
@@ -304,66 +310,76 @@
del client_call
del server_call
- def test6522(self):
+ def test_6522(self):
DEADLINE = time.time() + 5
DEADLINE_TOLERANCE = 0.25
METHOD = b'twinkies'
empty_metadata = ()
+ # Prologue
server_request_tag = object()
self.server.request_call(self.server_completion_queue,
self.server_completion_queue,
server_request_tag)
- client_call = self.client_channel.create_call(
- None, 0, self.client_completion_queue, METHOD, self.host_argument,
- DEADLINE)
+ client_call = self.client_channel.segregated_call(
+ 0, METHOD, self.host_argument, DEADLINE, None, None, ([(
+ [
+ cygrpc.SendInitialMetadataOperation(empty_metadata,
+ _EMPTY_FLAGS),
+ cygrpc.ReceiveInitialMetadataOperation(_EMPTY_FLAGS),
+ ],
+ object(),
+ ), (
+ [
+ cygrpc.ReceiveStatusOnClientOperation(_EMPTY_FLAGS),
+ ],
+ object(),
+ )]))
- # Prologue
- def perform_client_operations(operations, description):
- return self._perform_operations(operations, client_call,
- self.client_completion_queue,
- DEADLINE, description)
-
- client_event_future = perform_client_operations([
- cygrpc.SendInitialMetadataOperation(empty_metadata, _EMPTY_FLAGS),
- cygrpc.ReceiveInitialMetadataOperation(_EMPTY_FLAGS),
- ], "Client prologue")
+ client_initial_metadata_event_future = test_utilities.SimpleFuture(
+ client_call.next_event)
request_event = self.server_completion_queue.poll(deadline=DEADLINE)
server_call = request_event.call
def perform_server_operations(operations, description):
- return self._perform_operations(operations, server_call,
- self.server_completion_queue,
- DEADLINE, description)
+ return self._perform_queue_operations(operations, server_call,
+ self.server_completion_queue,
+ DEADLINE, description)
server_event_future = perform_server_operations([
cygrpc.SendInitialMetadataOperation(empty_metadata, _EMPTY_FLAGS),
], "Server prologue")
- client_event_future.result() # force completion
+ client_initial_metadata_event_future.result() # force completion
server_event_future.result()
# Messaging
for _ in range(10):
- client_event_future = perform_client_operations([
+ client_call.operate([
cygrpc.SendMessageOperation(b'', _EMPTY_FLAGS),
cygrpc.ReceiveMessageOperation(_EMPTY_FLAGS),
], "Client message")
+ client_message_event_future = test_utilities.SimpleFuture(
+ client_call.next_event)
server_event_future = perform_server_operations([
cygrpc.SendMessageOperation(b'', _EMPTY_FLAGS),
cygrpc.ReceiveMessageOperation(_EMPTY_FLAGS),
], "Server receive")
- client_event_future.result() # force completion
+ client_message_event_future.result() # force completion
server_event_future.result()
# Epilogue
- client_event_future = perform_client_operations([
+ client_call.operate([
cygrpc.SendCloseFromClientOperation(_EMPTY_FLAGS),
- cygrpc.ReceiveStatusOnClientOperation(_EMPTY_FLAGS)
], "Client epilogue")
+ # One for ReceiveStatusOnClient, one for SendCloseFromClient.
+ client_events_future = test_utilities.SimpleFuture(
+ lambda: {
+ client_call.next_event(),
+ client_call.next_event(),})
server_event_future = perform_server_operations([
cygrpc.ReceiveCloseOnServerOperation(_EMPTY_FLAGS),
@@ -371,7 +387,7 @@
empty_metadata, cygrpc.StatusCode.ok, b'', _EMPTY_FLAGS)
], "Server epilogue")
- client_event_future.result() # force completion
+ client_events_future.result() # force completion
server_event_future.result()
diff --git a/src/python/grpcio_tests/tests/unit/_cython/test_utilities.py b/src/python/grpcio_tests/tests/unit/_cython/test_utilities.py
index 4a00b9e..7d5eaaa 100644
--- a/src/python/grpcio_tests/tests/unit/_cython/test_utilities.py
+++ b/src/python/grpcio_tests/tests/unit/_cython/test_utilities.py
@@ -25,7 +25,7 @@
def wrapped_function():
try:
self._result = function(*args, **kwargs)
- except Exception as error:
+ except Exception as error: # pylint: disable=broad-except
self._error = error
self._result = None
@@ -41,7 +41,7 @@
self._thread.join()
if self._error:
# TODO(atash): re-raise exceptions in a way that preserves tracebacks
- raise self._error
+ raise self._error # pylint: disable=raising-bad-type
return self._result
diff --git a/src/python/grpcio_tests/tests/unit/_exit_test.py b/src/python/grpcio_tests/tests/unit/_exit_test.py
index 6e6d9de..f40f3ae 100644
--- a/src/python/grpcio_tests/tests/unit/_exit_test.py
+++ b/src/python/grpcio_tests/tests/unit/_exit_test.py
@@ -49,7 +49,7 @@
for process in processes:
try:
process.kill()
- except Exception:
+ except Exception: # pylint: disable=broad-except
pass
diff --git a/src/python/grpcio_tests/tests/unit/_from_grpc_import_star.py b/src/python/grpcio_tests/tests/unit/_from_grpc_import_star.py
index e683131..ad847ae 100644
--- a/src/python/grpcio_tests/tests/unit/_from_grpc_import_star.py
+++ b/src/python/grpcio_tests/tests/unit/_from_grpc_import_star.py
@@ -14,7 +14,7 @@
_BEFORE_IMPORT = tuple(globals())
-from grpc import *
+from grpc import * # pylint: disable=wildcard-import
_AFTER_IMPORT = tuple(globals())
diff --git a/src/python/grpcio_tests/tests/unit/_invalid_metadata_test.py b/src/python/grpcio_tests/tests/unit/_invalid_metadata_test.py
index 4edf0fc..f153089 100644
--- a/src/python/grpcio_tests/tests/unit/_invalid_metadata_test.py
+++ b/src/python/grpcio_tests/tests/unit/_invalid_metadata_test.py
@@ -81,29 +81,16 @@
request = b'\x07\x08'
metadata = (('InVaLiD', 'UnaryRequestFutureUnaryResponse'),)
expected_error_details = "metadata was invalid: %s" % metadata
- response_future = self._unary_unary.future(request, metadata=metadata)
- with self.assertRaises(grpc.RpcError) as exception_context:
- response_future.result()
- self.assertEqual(exception_context.exception.details(),
- expected_error_details)
- self.assertEqual(exception_context.exception.code(),
- grpc.StatusCode.INTERNAL)
- self.assertEqual(response_future.details(), expected_error_details)
- self.assertEqual(response_future.code(), grpc.StatusCode.INTERNAL)
+ with self.assertRaises(ValueError) as exception_context:
+ self._unary_unary.future(request, metadata=metadata)
def testUnaryRequestStreamResponse(self):
request = b'\x37\x58'
metadata = (('InVaLiD', 'UnaryRequestStreamResponse'),)
expected_error_details = "metadata was invalid: %s" % metadata
- response_iterator = self._unary_stream(request, metadata=metadata)
- with self.assertRaises(grpc.RpcError) as exception_context:
- next(response_iterator)
- self.assertEqual(exception_context.exception.details(),
- expected_error_details)
- self.assertEqual(exception_context.exception.code(),
- grpc.StatusCode.INTERNAL)
- self.assertEqual(response_iterator.details(), expected_error_details)
- self.assertEqual(response_iterator.code(), grpc.StatusCode.INTERNAL)
+ with self.assertRaises(ValueError) as exception_context:
+ self._unary_stream(request, metadata=metadata)
+ self.assertIn(expected_error_details, str(exception_context.exception))
def testStreamRequestBlockingUnaryResponse(self):
request_iterator = (
@@ -129,32 +116,18 @@
b'\x07\x08' for _ in range(test_constants.STREAM_LENGTH))
metadata = (('InVaLiD', 'StreamRequestFutureUnaryResponse'),)
expected_error_details = "metadata was invalid: %s" % metadata
- response_future = self._stream_unary.future(
- request_iterator, metadata=metadata)
- with self.assertRaises(grpc.RpcError) as exception_context:
- response_future.result()
- self.assertEqual(exception_context.exception.details(),
- expected_error_details)
- self.assertEqual(exception_context.exception.code(),
- grpc.StatusCode.INTERNAL)
- self.assertEqual(response_future.details(), expected_error_details)
- self.assertEqual(response_future.code(), grpc.StatusCode.INTERNAL)
+ with self.assertRaises(ValueError) as exception_context:
+ self._stream_unary.future(request_iterator, metadata=metadata)
+ self.assertIn(expected_error_details, str(exception_context.exception))
def testStreamRequestStreamResponse(self):
request_iterator = (
b'\x07\x08' for _ in range(test_constants.STREAM_LENGTH))
metadata = (('InVaLiD', 'StreamRequestStreamResponse'),)
expected_error_details = "metadata was invalid: %s" % metadata
- response_iterator = self._stream_stream(
- request_iterator, metadata=metadata)
- with self.assertRaises(grpc.RpcError) as exception_context:
- next(response_iterator)
- self.assertEqual(exception_context.exception.details(),
- expected_error_details)
- self.assertEqual(exception_context.exception.code(),
- grpc.StatusCode.INTERNAL)
- self.assertEqual(response_iterator.details(), expected_error_details)
- self.assertEqual(response_iterator.code(), grpc.StatusCode.INTERNAL)
+ with self.assertRaises(ValueError) as exception_context:
+ self._stream_stream(request_iterator, metadata=metadata)
+ self.assertIn(expected_error_details, str(exception_context.exception))
if __name__ == '__main__':
diff --git a/src/python/grpcio_tests/tests/unit/_invocation_defects_test.py b/src/python/grpcio_tests/tests/unit/_invocation_defects_test.py
index e40cca8..93a5fdf 100644
--- a/src/python/grpcio_tests/tests/unit/_invocation_defects_test.py
+++ b/src/python/grpcio_tests/tests/unit/_invocation_defects_test.py
@@ -165,11 +165,13 @@
def __next__(self):
if self._current >= self._high:
- raise Exception("This is a deliberate failure in a unit test.")
+ raise test_control.Defect()
else:
self._current += 1
return self._bytestring
+ next = __next__
+
def _unary_unary_multi_callable(channel):
return channel.unary_unary(_UNARY_UNARY)
diff --git a/src/python/grpcio_tests/tests/unit/_thread_cleanup_test.py b/src/python/grpcio_tests/tests/unit/_thread_cleanup_test.py
deleted file mode 100644
index 18f5af0..0000000
--- a/src/python/grpcio_tests/tests/unit/_thread_cleanup_test.py
+++ /dev/null
@@ -1,115 +0,0 @@
-# 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.
-"""Tests for CleanupThread."""
-
-import threading
-import time
-import unittest
-
-from grpc import _common
-
-_SHORT_TIME = 0.5
-_LONG_TIME = 5.0
-_EPSILON = 0.5
-
-
-def cleanup(timeout):
- if timeout is not None:
- time.sleep(timeout)
- else:
- time.sleep(_LONG_TIME)
-
-
-def slow_cleanup(timeout):
- # Don't respect timeout
- time.sleep(_LONG_TIME)
-
-
-class CleanupThreadTest(unittest.TestCase):
-
- def testTargetInvocation(self):
- event = threading.Event()
-
- def target(arg1, arg2, arg3=None):
- self.assertEqual('arg1', arg1)
- self.assertEqual('arg2', arg2)
- self.assertEqual('arg3', arg3)
- event.set()
-
- cleanup_thread = _common.CleanupThread(
- behavior=lambda x: None,
- target=target,
- name='test-name',
- args=('arg1', 'arg2'),
- kwargs={
- 'arg3': 'arg3'
- })
- cleanup_thread.start()
- cleanup_thread.join()
- self.assertEqual(cleanup_thread.name, 'test-name')
- self.assertTrue(event.is_set())
-
- def testJoinNoTimeout(self):
- cleanup_thread = _common.CleanupThread(behavior=cleanup)
- cleanup_thread.start()
- start_time = time.time()
- cleanup_thread.join()
- end_time = time.time()
- self.assertAlmostEqual(
- _LONG_TIME, end_time - start_time, delta=_EPSILON)
-
- def testJoinTimeout(self):
- cleanup_thread = _common.CleanupThread(behavior=cleanup)
- cleanup_thread.start()
- start_time = time.time()
- cleanup_thread.join(_SHORT_TIME)
- end_time = time.time()
- self.assertAlmostEqual(
- _SHORT_TIME, end_time - start_time, delta=_EPSILON)
-
- def testJoinTimeoutSlowBehavior(self):
- cleanup_thread = _common.CleanupThread(behavior=slow_cleanup)
- cleanup_thread.start()
- start_time = time.time()
- cleanup_thread.join(_SHORT_TIME)
- end_time = time.time()
- self.assertAlmostEqual(
- _LONG_TIME, end_time - start_time, delta=_EPSILON)
-
- def testJoinTimeoutSlowTarget(self):
- event = threading.Event()
-
- def target():
- event.wait(_LONG_TIME)
-
- cleanup_thread = _common.CleanupThread(behavior=cleanup, target=target)
- cleanup_thread.start()
- start_time = time.time()
- cleanup_thread.join(_SHORT_TIME)
- end_time = time.time()
- self.assertAlmostEqual(
- _SHORT_TIME, end_time - start_time, delta=_EPSILON)
- event.set()
-
- def testJoinZeroTimeout(self):
- cleanup_thread = _common.CleanupThread(behavior=cleanup)
- cleanup_thread.start()
- start_time = time.time()
- cleanup_thread.join(0)
- end_time = time.time()
- self.assertAlmostEqual(0, end_time - start_time, delta=_EPSILON)
-
-
-if __name__ == '__main__':
- unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/beta/_beta_features_test.py b/src/python/grpcio_tests/tests/unit/beta/_beta_features_test.py
index 61c03f6..b43c647 100644
--- a/src/python/grpcio_tests/tests/unit/beta/_beta_features_test.py
+++ b/src/python/grpcio_tests/tests/unit/beta/_beta_features_test.py
@@ -65,7 +65,7 @@
self._serviced = True
self._condition.notify_all()
return
- yield
+ yield # pylint: disable=unreachable
def stream_unary(self, request_iterator, context):
for request in request_iterator:
diff --git a/src/ruby/end2end/client_memory_usage_client.rb b/src/ruby/end2end/client_memory_usage_client.rb
new file mode 100755
index 0000000..c6268b4
--- /dev/null
+++ b/src/ruby/end2end/client_memory_usage_client.rb
@@ -0,0 +1,44 @@
+#!/usr/bin/env ruby
+
+# Copyright 2018 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.
+
+require_relative './end2end_common'
+require 'objspace'
+
+def main
+ server_port = ''
+ loop_count = 200
+
+ OptionParser.new do |opts|
+ opts.on('--client_control_port=P', String) do
+ STDERR.puts 'client_control_port ignored'
+ end
+ opts.on('--server_port=P', String) do |p|
+ server_port = p
+ end
+ end.parse!
+
+ loop_count.times do
+ stub = Echo::EchoServer::Stub.new("localhost:#{server_port}", :this_channel_is_insecure)
+ stub.echo(Echo::EchoRequest.new(request: 'client/child'))
+
+ # Get memory usage of all objects
+ ObjectSpace.memsize_of_all
+ end
+
+ STDERR.puts "Succeeded in getting memory usage for #{loop_count} times"
+end
+
+main
diff --git a/src/ruby/end2end/client_memory_usage_driver.rb b/src/ruby/end2end/client_memory_usage_driver.rb
new file mode 100755
index 0000000..9e46d7e
--- /dev/null
+++ b/src/ruby/end2end/client_memory_usage_driver.rb
@@ -0,0 +1,36 @@
+#!/usr/bin/env ruby
+
+# Copyright 2018 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.
+
+require_relative './end2end_common'
+
+def main
+ STDERR.puts 'start server'
+ server_runner = ServerRunner.new(EchoServerImpl)
+ server_port = server_runner.run
+ STDERR.puts 'start client'
+ _, client_pid = start_client('client_memory_usage_client.rb', server_port)
+
+ Process.wait(client_pid)
+
+ client_exit_code = $CHILD_STATUS
+ if client_exit_code != 0
+ raise "Getting memory usage was failed, exit code #{client_exit_code}"
+ end
+ensure
+ server_runner.stop
+end
+
+main
diff --git a/src/ruby/end2end/multiple_killed_watching_threads_driver.rb b/src/ruby/end2end/multiple_killed_watching_threads_driver.rb
index 8f078cf..8ec2073 100755
--- a/src/ruby/end2end/multiple_killed_watching_threads_driver.rb
+++ b/src/ruby/end2end/multiple_killed_watching_threads_driver.rb
@@ -54,8 +54,14 @@
end
def main
+ STDERR.puts '10 iterations, sleep 0.1 before killing thread'
run_multiple_killed_watches(10, 0.1)
+ STDERR.puts '1000 iterations, sleep 0.001 before killing thread'
run_multiple_killed_watches(1000, 0.001)
+ STDERR.puts '10000 iterations, sleep 0.00001 before killing thread'
+ run_multiple_killed_watches(10_000, 0.00001)
+ STDERR.puts '20000 iterations, sleep 0.00001 before killing thread'
+ run_multiple_killed_watches(20_000, 0.00001)
end
main
diff --git a/src/ruby/ext/grpc/extconf.rb b/src/ruby/ext/grpc/extconf.rb
index e8e87e4..4760f33 100644
--- a/src/ruby/ext/grpc/extconf.rb
+++ b/src/ruby/ext/grpc/extconf.rb
@@ -84,7 +84,7 @@
end
if grpc_config == 'dbg'
- $CFLAGS << ' -O0'
+ $CFLAGS << ' -O0 -ggdb3'
end
$LDFLAGS << ' -Wl,-wrap,memcpy' if RUBY_PLATFORM =~ /linux/
diff --git a/src/ruby/ext/grpc/rb_call.c b/src/ruby/ext/grpc/rb_call.c
index 7f3ca2a..b6c0791 100644
--- a/src/ruby/ext/grpc/rb_call.c
+++ b/src/ruby/ext/grpc/rb_call.c
@@ -103,23 +103,11 @@
xfree(p);
}
-static size_t md_ary_datasize(const void* p) {
- const grpc_metadata_array* const ary = (grpc_metadata_array*)p;
- size_t i, datasize = sizeof(grpc_metadata_array);
- for (i = 0; i < ary->count; ++i) {
- const grpc_metadata* const md = &ary->metadata[i];
- datasize += GRPC_SLICE_LENGTH(md->key);
- datasize += GRPC_SLICE_LENGTH(md->value);
- }
- datasize += ary->capacity * sizeof(grpc_metadata);
- return datasize;
-}
-
static const rb_data_type_t grpc_rb_md_ary_data_type = {
"grpc_metadata_array",
{GRPC_RB_GC_NOT_MARKED,
GRPC_RB_GC_DONT_FREE,
- md_ary_datasize,
+ GRPC_RB_MEMSIZE_UNAVAILABLE,
{NULL, NULL}},
NULL,
NULL,
diff --git a/src/ruby/ext/grpc/rb_channel.c b/src/ruby/ext/grpc/rb_channel.c
index e8bfeb3..3f0dc53 100644
--- a/src/ruby/ext/grpc/rb_channel.c
+++ b/src/ruby/ext/grpc/rb_channel.c
@@ -315,7 +315,7 @@
}
typedef struct watch_state_stack {
- grpc_channel* channel;
+ bg_watched_channel* bg_wrapped;
gpr_timespec deadline;
int last_state;
} watch_state_stack;
@@ -328,15 +328,15 @@
gpr_mu_lock(&global_connection_polling_mu);
// its unsafe to do a "watch" after "channel polling abort" because the cq has
// been shut down.
- if (abort_channel_polling) {
+ if (abort_channel_polling || stack->bg_wrapped->channel_destroyed) {
gpr_mu_unlock(&global_connection_polling_mu);
return (void*)0;
}
op = gpr_zalloc(sizeof(watch_state_op));
op->op_type = WATCH_STATE_API;
- grpc_channel_watch_connectivity_state(stack->channel, stack->last_state,
- stack->deadline, channel_polling_cq,
- op);
+ grpc_channel_watch_connectivity_state(stack->bg_wrapped->channel,
+ stack->last_state, stack->deadline,
+ channel_polling_cq, op);
while (!op->op.api_callback_args.called_back) {
gpr_cv_wait(&global_connection_polling_cv, &global_connection_polling_mu,
@@ -388,7 +388,7 @@
return Qnil;
}
- stack.channel = wrapper->bg_wrapped->channel;
+ stack.bg_wrapped = wrapper->bg_wrapped;
stack.deadline = grpc_rb_time_timeval(deadline, 0),
stack.last_state = NUM2LONG(last_state);
diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.c b/src/ruby/ext/grpc/rb_grpc_imports.generated.c
index a12819e..02f84c0 100644
--- a/src/ruby/ext/grpc/rb_grpc_imports.generated.c
+++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.c
@@ -138,6 +138,12 @@
grpc_server_add_secure_http2_port_type grpc_server_add_secure_http2_port_import;
grpc_call_set_credentials_type grpc_call_set_credentials_import;
grpc_server_credentials_set_auth_metadata_processor_type grpc_server_credentials_set_auth_metadata_processor_import;
+grpc_alts_credentials_client_options_create_type grpc_alts_credentials_client_options_create_import;
+grpc_alts_credentials_server_options_create_type grpc_alts_credentials_server_options_create_import;
+grpc_alts_credentials_client_options_add_target_service_account_type grpc_alts_credentials_client_options_add_target_service_account_import;
+grpc_alts_credentials_options_destroy_type grpc_alts_credentials_options_destroy_import;
+grpc_alts_credentials_create_type grpc_alts_credentials_create_import;
+grpc_alts_server_credentials_create_type grpc_alts_server_credentials_create_import;
grpc_raw_byte_buffer_create_type grpc_raw_byte_buffer_create_import;
grpc_raw_compressed_byte_buffer_create_type grpc_raw_compressed_byte_buffer_create_import;
grpc_byte_buffer_copy_type grpc_byte_buffer_copy_import;
@@ -208,6 +214,7 @@
gpr_cpu_current_cpu_type gpr_cpu_current_cpu_import;
gpr_log_severity_string_type gpr_log_severity_string_import;
gpr_log_type gpr_log_import;
+gpr_should_log_type gpr_should_log_import;
gpr_log_message_type gpr_log_message_import;
gpr_set_log_verbosity_type gpr_set_log_verbosity_import;
gpr_log_verbosity_init_type gpr_log_verbosity_init_import;
@@ -379,6 +386,12 @@
grpc_server_add_secure_http2_port_import = (grpc_server_add_secure_http2_port_type) GetProcAddress(library, "grpc_server_add_secure_http2_port");
grpc_call_set_credentials_import = (grpc_call_set_credentials_type) GetProcAddress(library, "grpc_call_set_credentials");
grpc_server_credentials_set_auth_metadata_processor_import = (grpc_server_credentials_set_auth_metadata_processor_type) GetProcAddress(library, "grpc_server_credentials_set_auth_metadata_processor");
+ grpc_alts_credentials_client_options_create_import = (grpc_alts_credentials_client_options_create_type) GetProcAddress(library, "grpc_alts_credentials_client_options_create");
+ grpc_alts_credentials_server_options_create_import = (grpc_alts_credentials_server_options_create_type) GetProcAddress(library, "grpc_alts_credentials_server_options_create");
+ grpc_alts_credentials_client_options_add_target_service_account_import = (grpc_alts_credentials_client_options_add_target_service_account_type) GetProcAddress(library, "grpc_alts_credentials_client_options_add_target_service_account");
+ grpc_alts_credentials_options_destroy_import = (grpc_alts_credentials_options_destroy_type) GetProcAddress(library, "grpc_alts_credentials_options_destroy");
+ grpc_alts_credentials_create_import = (grpc_alts_credentials_create_type) GetProcAddress(library, "grpc_alts_credentials_create");
+ grpc_alts_server_credentials_create_import = (grpc_alts_server_credentials_create_type) GetProcAddress(library, "grpc_alts_server_credentials_create");
grpc_raw_byte_buffer_create_import = (grpc_raw_byte_buffer_create_type) GetProcAddress(library, "grpc_raw_byte_buffer_create");
grpc_raw_compressed_byte_buffer_create_import = (grpc_raw_compressed_byte_buffer_create_type) GetProcAddress(library, "grpc_raw_compressed_byte_buffer_create");
grpc_byte_buffer_copy_import = (grpc_byte_buffer_copy_type) GetProcAddress(library, "grpc_byte_buffer_copy");
@@ -449,6 +462,7 @@
gpr_cpu_current_cpu_import = (gpr_cpu_current_cpu_type) GetProcAddress(library, "gpr_cpu_current_cpu");
gpr_log_severity_string_import = (gpr_log_severity_string_type) GetProcAddress(library, "gpr_log_severity_string");
gpr_log_import = (gpr_log_type) GetProcAddress(library, "gpr_log");
+ gpr_should_log_import = (gpr_should_log_type) GetProcAddress(library, "gpr_should_log");
gpr_log_message_import = (gpr_log_message_type) GetProcAddress(library, "gpr_log_message");
gpr_set_log_verbosity_import = (gpr_set_log_verbosity_type) GetProcAddress(library, "gpr_set_log_verbosity");
gpr_log_verbosity_init_import = (gpr_log_verbosity_init_type) GetProcAddress(library, "gpr_log_verbosity_init");
diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h
index 089cb8a..b2186a6 100644
--- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h
+++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h
@@ -389,6 +389,24 @@
typedef void(*grpc_server_credentials_set_auth_metadata_processor_type)(grpc_server_credentials* creds, grpc_auth_metadata_processor processor);
extern grpc_server_credentials_set_auth_metadata_processor_type grpc_server_credentials_set_auth_metadata_processor_import;
#define grpc_server_credentials_set_auth_metadata_processor grpc_server_credentials_set_auth_metadata_processor_import
+typedef grpc_alts_credentials_options*(*grpc_alts_credentials_client_options_create_type)();
+extern grpc_alts_credentials_client_options_create_type grpc_alts_credentials_client_options_create_import;
+#define grpc_alts_credentials_client_options_create grpc_alts_credentials_client_options_create_import
+typedef grpc_alts_credentials_options*(*grpc_alts_credentials_server_options_create_type)();
+extern grpc_alts_credentials_server_options_create_type grpc_alts_credentials_server_options_create_import;
+#define grpc_alts_credentials_server_options_create grpc_alts_credentials_server_options_create_import
+typedef void(*grpc_alts_credentials_client_options_add_target_service_account_type)(grpc_alts_credentials_options* options, const char* service_account);
+extern grpc_alts_credentials_client_options_add_target_service_account_type grpc_alts_credentials_client_options_add_target_service_account_import;
+#define grpc_alts_credentials_client_options_add_target_service_account grpc_alts_credentials_client_options_add_target_service_account_import
+typedef void(*grpc_alts_credentials_options_destroy_type)(grpc_alts_credentials_options* options);
+extern grpc_alts_credentials_options_destroy_type grpc_alts_credentials_options_destroy_import;
+#define grpc_alts_credentials_options_destroy grpc_alts_credentials_options_destroy_import
+typedef grpc_channel_credentials*(*grpc_alts_credentials_create_type)(const grpc_alts_credentials_options* options);
+extern grpc_alts_credentials_create_type grpc_alts_credentials_create_import;
+#define grpc_alts_credentials_create grpc_alts_credentials_create_import
+typedef grpc_server_credentials*(*grpc_alts_server_credentials_create_type)(const grpc_alts_credentials_options* options);
+extern grpc_alts_server_credentials_create_type grpc_alts_server_credentials_create_import;
+#define grpc_alts_server_credentials_create grpc_alts_server_credentials_create_import
typedef grpc_byte_buffer*(*grpc_raw_byte_buffer_create_type)(grpc_slice* slices, size_t nslices);
extern grpc_raw_byte_buffer_create_type grpc_raw_byte_buffer_create_import;
#define grpc_raw_byte_buffer_create grpc_raw_byte_buffer_create_import
@@ -599,6 +617,9 @@
typedef void(*gpr_log_type)(const char* file, int line, gpr_log_severity severity, const char* format, ...) GPR_PRINT_FORMAT_CHECK(4, 5);
extern gpr_log_type gpr_log_import;
#define gpr_log gpr_log_import
+typedef int(*gpr_should_log_type)(gpr_log_severity severity);
+extern gpr_should_log_type gpr_should_log_import;
+#define gpr_should_log gpr_should_log_import
typedef void(*gpr_log_message_type)(const char* file, int line, gpr_log_severity severity, const char* message);
extern gpr_log_message_type gpr_log_message_import;
#define gpr_log_message gpr_log_message_import
diff --git a/src/ruby/lib/grpc/generic/bidi_call.rb b/src/ruby/lib/grpc/generic/bidi_call.rb
index 086455d..ffb232b 100644
--- a/src/ruby/lib/grpc/generic/bidi_call.rb
+++ b/src/ruby/lib/grpc/generic/bidi_call.rb
@@ -124,12 +124,18 @@
def read_using_run_batch
ops = { RECV_MESSAGE => nil }
ops[RECV_INITIAL_METADATA] = nil unless @metadata_received
- batch_result = @call.run_batch(ops)
- unless @metadata_received
- @call.metadata = batch_result.metadata
- @metadata_received = true
+ begin
+ batch_result = @call.run_batch(ops)
+ unless @metadata_received
+ @call.metadata = batch_result.metadata
+ @metadata_received = true
+ end
+ batch_result
+ rescue GRPC::Core::CallError => e
+ GRPC.logger.warn('bidi call: read_using_run_batch failed')
+ GRPC.logger.warn(e)
+ nil
end
- batch_result
end
# set_output_stream_done is relevant on client-side
@@ -155,7 +161,12 @@
GRPC.logger.debug("bidi-write-loop: #{count} writes done")
if is_client
GRPC.logger.debug("bidi-write-loop: client sent #{count}, waiting")
- @call.run_batch(SEND_CLOSE_FROM_CLIENT => nil)
+ begin
+ @call.run_batch(SEND_CLOSE_FROM_CLIENT => nil)
+ rescue GRPC::Core::CallError => e
+ GRPC.logger.warn('bidi-write-loop: send close failed')
+ GRPC.logger.warn(e)
+ end
GRPC.logger.debug('bidi-write-loop: done')
end
GRPC.logger.debug('bidi-write-loop: finished')
@@ -187,7 +198,7 @@
batch_result = read_using_run_batch
# handle the next message
- if batch_result.message.nil?
+ if batch_result.nil? || batch_result.message.nil?
GRPC.logger.debug("bidi-read-loop: null batch #{batch_result}")
if is_client
diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb
index 256a543..15f3751 100644
--- a/src/ruby/lib/grpc/version.rb
+++ b/src/ruby/lib/grpc/version.rb
@@ -14,5 +14,5 @@
# GRPC contains the General RPC module.
module GRPC
- VERSION = '1.11.0.dev'
+ VERSION = '1.13.0.dev'
end
diff --git a/src/ruby/pb/generate_proto_ruby.sh b/src/ruby/pb/generate_proto_ruby.sh
index d25eff5..ec6e2ee 100755
--- a/src/ruby/pb/generate_proto_ruby.sh
+++ b/src/ruby/pb/generate_proto_ruby.sh
@@ -32,7 +32,13 @@
--plugin=$PLUGIN
$PROTOC -I . \
- src/proto/grpc/testing/{messages,payloads,stats,services,control}.proto \
+ src/proto/grpc/core/stats.proto \
+ --grpc_out=src/ruby/qps \
+ --ruby_out=src/ruby/qps \
+ --plugin=$PLUGIN
+
+$PROTOC -I . \
+ src/proto/grpc/testing/{messages,payloads,stats,benchmark_service,report_qps_scenario_service,worker_service,control}.proto \
--grpc_out=src/ruby/qps \
--ruby_out=src/ruby/qps \
--plugin=$PLUGIN
diff --git a/src/ruby/pb/grpc/health/v1/health_services_pb.rb b/src/ruby/pb/grpc/health/v1/health_services_pb.rb
index 520f8e7..169e160 100644
--- a/src/ruby/pb/grpc/health/v1/health_services_pb.rb
+++ b/src/ruby/pb/grpc/health/v1/health_services_pb.rb
@@ -1,7 +1,7 @@
# Generated by the protocol buffer compiler. DO NOT EDIT!
# Source: grpc/health/v1/health.proto for package 'grpc.health.v1'
# Original file comments:
-# Copyright 2015 gRPC authors.
+# Copyright 2015 The gRPC Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -15,6 +15,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+# The canonical version of this proto can be found at
+# https://github.com/grpc/grpc-proto/blob/master/grpc/health/v1/health.proto
+#
require 'grpc'
require 'grpc/health/v1/health_pb'
diff --git a/src/ruby/qps/client.rb b/src/ruby/qps/client.rb
index 0426aee..d573d82 100644
--- a/src/ruby/qps/client.rb
+++ b/src/ruby/qps/client.rb
@@ -23,7 +23,7 @@
require 'grpc'
require 'histogram'
-require 'src/proto/grpc/testing/services_services_pb'
+require 'src/proto/grpc/testing/benchmark_service_services_pb'
class Poisson
def interarrival
diff --git a/src/ruby/qps/proxy-worker.rb b/src/ruby/qps/proxy-worker.rb
index 4c7c510..5f23d89 100755
--- a/src/ruby/qps/proxy-worker.rb
+++ b/src/ruby/qps/proxy-worker.rb
@@ -27,7 +27,7 @@
require 'etc'
require 'facter'
require 'qps-common'
-require 'src/proto/grpc/testing/services_services_pb'
+require 'src/proto/grpc/testing/worker_service_services_pb'
require 'src/proto/grpc/testing/proxy-service_services_pb'
class ProxyBenchmarkClientServiceImpl < Grpc::Testing::ProxyClientService::Service
diff --git a/src/ruby/qps/server.rb b/src/ruby/qps/server.rb
index 90218ea..dccc64e 100644
--- a/src/ruby/qps/server.rb
+++ b/src/ruby/qps/server.rb
@@ -24,7 +24,7 @@
require 'grpc'
require 'qps-common'
require 'src/proto/grpc/testing/messages_pb'
-require 'src/proto/grpc/testing/services_services_pb'
+require 'src/proto/grpc/testing/benchmark_service_services_pb'
require 'src/proto/grpc/testing/stats_pb'
class BenchmarkServiceImpl < Grpc::Testing::BenchmarkService::Service
diff --git a/src/ruby/qps/src/proto/grpc/core/stats_pb.rb b/src/ruby/qps/src/proto/grpc/core/stats_pb.rb
new file mode 100644
index 0000000..59c0578
--- /dev/null
+++ b/src/ruby/qps/src/proto/grpc/core/stats_pb.rb
@@ -0,0 +1,33 @@
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: src/proto/grpc/core/stats.proto
+
+require 'google/protobuf'
+
+Google::Protobuf::DescriptorPool.generated_pool.build do
+ add_message "grpc.core.Bucket" do
+ optional :start, :double, 1
+ optional :count, :uint64, 2
+ end
+ add_message "grpc.core.Histogram" do
+ repeated :buckets, :message, 1, "grpc.core.Bucket"
+ end
+ add_message "grpc.core.Metric" do
+ optional :name, :string, 1
+ oneof :value do
+ optional :count, :uint64, 10
+ optional :histogram, :message, 11, "grpc.core.Histogram"
+ end
+ end
+ add_message "grpc.core.Stats" do
+ repeated :metrics, :message, 1, "grpc.core.Metric"
+ end
+end
+
+module Grpc
+ module Core
+ Bucket = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.core.Bucket").msgclass
+ Histogram = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.core.Histogram").msgclass
+ Metric = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.core.Metric").msgclass
+ Stats = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.core.Stats").msgclass
+ end
+end
diff --git a/src/ruby/qps/src/proto/grpc/testing/services_pb.rb b/src/ruby/qps/src/proto/grpc/testing/benchmark_service_pb.rb
similarity index 71%
copy from src/ruby/qps/src/proto/grpc/testing/services_pb.rb
copy to src/ruby/qps/src/proto/grpc/testing/benchmark_service_pb.rb
index 5ce13bf..0bd3625 100644
--- a/src/ruby/qps/src/proto/grpc/testing/services_pb.rb
+++ b/src/ruby/qps/src/proto/grpc/testing/benchmark_service_pb.rb
@@ -1,10 +1,9 @@
# Generated by the protocol buffer compiler. DO NOT EDIT!
-# source: src/proto/grpc/testing/services.proto
+# source: src/proto/grpc/testing/benchmark_service.proto
require 'google/protobuf'
require 'src/proto/grpc/testing/messages_pb'
-require 'src/proto/grpc/testing/control_pb'
Google::Protobuf::DescriptorPool.generated_pool.build do
end
diff --git a/src/ruby/qps/src/proto/grpc/testing/benchmark_service_services_pb.rb b/src/ruby/qps/src/proto/grpc/testing/benchmark_service_services_pb.rb
new file mode 100644
index 0000000..65e5a75
--- /dev/null
+++ b/src/ruby/qps/src/proto/grpc/testing/benchmark_service_services_pb.rb
@@ -0,0 +1,56 @@
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# Source: src/proto/grpc/testing/benchmark_service.proto for package 'grpc.testing'
+# Original file comments:
+# 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.
+#
+# An integration test service that covers all the method signature permutations
+# of unary/streaming requests/responses.
+
+require 'grpc'
+require 'src/proto/grpc/testing/benchmark_service_pb'
+
+module Grpc
+ module Testing
+ module BenchmarkService
+ class Service
+
+ include GRPC::GenericService
+
+ self.marshal_class_method = :encode
+ self.unmarshal_class_method = :decode
+ self.service_name = 'grpc.testing.BenchmarkService'
+
+ # One request followed by one response.
+ # The server returns the client payload as-is.
+ rpc :UnaryCall, SimpleRequest, SimpleResponse
+ # Repeated sequence of one request followed by one response.
+ # Should be called streaming ping-pong
+ # The server returns the client payload as-is on each response
+ rpc :StreamingCall, stream(SimpleRequest), stream(SimpleResponse)
+ # Single-sided unbounded streaming from client to server
+ # The server returns the client payload as-is once the client does WritesDone
+ rpc :StreamingFromClient, stream(SimpleRequest), SimpleResponse
+ # Single-sided unbounded streaming from server to client
+ # The server repeatedly returns the client payload as-is
+ rpc :StreamingFromServer, SimpleRequest, stream(SimpleResponse)
+ # Two-sided unbounded streaming between server to client
+ # Both sides send the content of their own choice to the other
+ rpc :StreamingBothWays, stream(SimpleRequest), stream(SimpleResponse)
+ end
+
+ Stub = Service.rpc_stub_class
+ end
+ end
+end
diff --git a/src/ruby/qps/src/proto/grpc/testing/control_pb.rb b/src/ruby/qps/src/proto/grpc/testing/control_pb.rb
index 02207a2..5acc7fc 100644
--- a/src/ruby/qps/src/proto/grpc/testing/control_pb.rb
+++ b/src/ruby/qps/src/proto/grpc/testing/control_pb.rb
@@ -20,6 +20,14 @@
add_message "grpc.testing.SecurityParams" do
optional :use_test_ca, :bool, 1
optional :server_host_override, :string, 2
+ optional :cred_type, :string, 3
+ end
+ add_message "grpc.testing.ChannelArg" do
+ optional :name, :string, 1
+ oneof :value do
+ optional :str_value, :string, 2
+ optional :int_value, :int32, 3
+ end
end
add_message "grpc.testing.ClientConfig" do
repeated :server_targets, :string, 1
@@ -35,6 +43,10 @@
repeated :core_list, :int32, 13
optional :core_limit, :int32, 14
optional :other_client_api, :string, 15
+ repeated :channel_args, :message, 16, "grpc.testing.ChannelArg"
+ optional :threads_per_cq, :int32, 17
+ optional :messages_per_stream, :int32, 18
+ optional :use_coalesce_api, :bool, 19
end
add_message "grpc.testing.ClientStatus" do
optional :stats, :message, 1, "grpc.testing.ClientStats"
@@ -57,6 +69,9 @@
optional :payload_config, :message, 9, "grpc.testing.PayloadConfig"
repeated :core_list, :int32, 10
optional :other_server_api, :string, 11
+ optional :threads_per_cq, :int32, 12
+ optional :resource_quota_size, :int32, 1001
+ repeated :channel_args, :message, 1002, "grpc.testing.ChannelArg"
end
add_message "grpc.testing.ServerArgs" do
oneof :argtype do
@@ -101,6 +116,13 @@
optional :latency_95, :double, 9
optional :latency_99, :double, 10
optional :latency_999, :double, 11
+ optional :server_cpu_usage, :double, 12
+ optional :successful_requests_per_second, :double, 13
+ optional :failed_requests_per_second, :double, 14
+ optional :client_polls_per_request, :double, 15
+ optional :server_polls_per_request, :double, 16
+ optional :server_queries_per_cpu_sec, :double, 17
+ optional :client_queries_per_cpu_sec, :double, 18
end
add_message "grpc.testing.ScenarioResult" do
optional :scenario, :message, 1, "grpc.testing.Scenario"
@@ -111,6 +133,7 @@
optional :summary, :message, 6, "grpc.testing.ScenarioResultSummary"
repeated :client_success, :bool, 7
repeated :server_success, :bool, 8
+ repeated :request_results, :message, 9, "grpc.testing.RequestResultCount"
end
add_enum "grpc.testing.ClientType" do
value :SYNC_CLIENT, 0
@@ -126,6 +149,9 @@
add_enum "grpc.testing.RpcType" do
value :UNARY, 0
value :STREAMING, 1
+ value :STREAMING_FROM_CLIENT, 2
+ value :STREAMING_FROM_SERVER, 3
+ value :STREAMING_BOTH_WAYS, 4
end
end
@@ -135,6 +161,7 @@
ClosedLoopParams = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ClosedLoopParams").msgclass
LoadParams = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.LoadParams").msgclass
SecurityParams = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.SecurityParams").msgclass
+ ChannelArg = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ChannelArg").msgclass
ClientConfig = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ClientConfig").msgclass
ClientStatus = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ClientStatus").msgclass
Mark = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.Mark").msgclass
diff --git a/src/ruby/qps/src/proto/grpc/testing/services_pb.rb b/src/ruby/qps/src/proto/grpc/testing/report_qps_scenario_service_pb.rb
similarity index 71%
rename from src/ruby/qps/src/proto/grpc/testing/services_pb.rb
rename to src/ruby/qps/src/proto/grpc/testing/report_qps_scenario_service_pb.rb
index 5ce13bf..1b43e37 100644
--- a/src/ruby/qps/src/proto/grpc/testing/services_pb.rb
+++ b/src/ruby/qps/src/proto/grpc/testing/report_qps_scenario_service_pb.rb
@@ -1,9 +1,8 @@
# Generated by the protocol buffer compiler. DO NOT EDIT!
-# source: src/proto/grpc/testing/services.proto
+# source: src/proto/grpc/testing/report_qps_scenario_service.proto
require 'google/protobuf'
-require 'src/proto/grpc/testing/messages_pb'
require 'src/proto/grpc/testing/control_pb'
Google::Protobuf::DescriptorPool.generated_pool.build do
end
diff --git a/src/ruby/qps/src/proto/grpc/testing/report_qps_scenario_service_services_pb.rb b/src/ruby/qps/src/proto/grpc/testing/report_qps_scenario_service_services_pb.rb
new file mode 100644
index 0000000..ddc81be
--- /dev/null
+++ b/src/ruby/qps/src/proto/grpc/testing/report_qps_scenario_service_services_pb.rb
@@ -0,0 +1,42 @@
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# Source: src/proto/grpc/testing/report_qps_scenario_service.proto for package 'grpc.testing'
+# Original file comments:
+# 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.
+#
+# An integration test service that covers all the method signature permutations
+# of unary/streaming requests/responses.
+
+require 'grpc'
+require 'src/proto/grpc/testing/report_qps_scenario_service_pb'
+
+module Grpc
+ module Testing
+ module ReportQpsScenarioService
+ class Service
+
+ include GRPC::GenericService
+
+ self.marshal_class_method = :encode
+ self.unmarshal_class_method = :decode
+ self.service_name = 'grpc.testing.ReportQpsScenarioService'
+
+ # Report results of a QPS test benchmark scenario.
+ rpc :ReportScenario, ScenarioResult, Void
+ end
+
+ Stub = Service.rpc_stub_class
+ end
+ end
+end
diff --git a/src/ruby/qps/src/proto/grpc/testing/stats_pb.rb b/src/ruby/qps/src/proto/grpc/testing/stats_pb.rb
index 41f75be..2069840 100644
--- a/src/ruby/qps/src/proto/grpc/testing/stats_pb.rb
+++ b/src/ruby/qps/src/proto/grpc/testing/stats_pb.rb
@@ -3,11 +3,16 @@
require 'google/protobuf'
+require 'src/proto/grpc/core/stats_pb'
Google::Protobuf::DescriptorPool.generated_pool.build do
add_message "grpc.testing.ServerStats" do
optional :time_elapsed, :double, 1
optional :time_user, :double, 2
optional :time_system, :double, 3
+ optional :total_cpu_time, :uint64, 4
+ optional :idle_cpu_time, :uint64, 5
+ optional :cq_poll_count, :uint64, 6
+ optional :core_stats, :message, 7, "grpc.core.Stats"
end
add_message "grpc.testing.HistogramParams" do
optional :resolution, :double, 1
@@ -21,11 +26,18 @@
optional :sum_of_squares, :double, 5
optional :count, :double, 6
end
+ add_message "grpc.testing.RequestResultCount" do
+ optional :status_code, :int32, 1
+ optional :count, :int64, 2
+ end
add_message "grpc.testing.ClientStats" do
optional :latencies, :message, 1, "grpc.testing.HistogramData"
optional :time_elapsed, :double, 2
optional :time_user, :double, 3
optional :time_system, :double, 4
+ repeated :request_results, :message, 5, "grpc.testing.RequestResultCount"
+ optional :cq_poll_count, :uint64, 6
+ optional :core_stats, :message, 7, "grpc.core.Stats"
end
end
@@ -34,6 +46,7 @@
ServerStats = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ServerStats").msgclass
HistogramParams = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.HistogramParams").msgclass
HistogramData = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.HistogramData").msgclass
+ RequestResultCount = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.RequestResultCount").msgclass
ClientStats = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ClientStats").msgclass
end
end
diff --git a/src/ruby/qps/src/proto/grpc/testing/services_pb.rb b/src/ruby/qps/src/proto/grpc/testing/worker_service_pb.rb
similarity index 71%
copy from src/ruby/qps/src/proto/grpc/testing/services_pb.rb
copy to src/ruby/qps/src/proto/grpc/testing/worker_service_pb.rb
index 5ce13bf..18b6345 100644
--- a/src/ruby/qps/src/proto/grpc/testing/services_pb.rb
+++ b/src/ruby/qps/src/proto/grpc/testing/worker_service_pb.rb
@@ -1,9 +1,8 @@
# Generated by the protocol buffer compiler. DO NOT EDIT!
-# source: src/proto/grpc/testing/services.proto
+# source: src/proto/grpc/testing/worker_service.proto
require 'google/protobuf'
-require 'src/proto/grpc/testing/messages_pb'
require 'src/proto/grpc/testing/control_pb'
Google::Protobuf::DescriptorPool.generated_pool.build do
end
diff --git a/src/ruby/qps/src/proto/grpc/testing/services_services_pb.rb b/src/ruby/qps/src/proto/grpc/testing/worker_service_services_pb.rb
similarity index 74%
rename from src/ruby/qps/src/proto/grpc/testing/services_services_pb.rb
rename to src/ruby/qps/src/proto/grpc/testing/worker_service_services_pb.rb
index 1d8b619..a7ecc95 100644
--- a/src/ruby/qps/src/proto/grpc/testing/services_services_pb.rb
+++ b/src/ruby/qps/src/proto/grpc/testing/worker_service_services_pb.rb
@@ -1,5 +1,5 @@
# Generated by the protocol buffer compiler. DO NOT EDIT!
-# Source: src/proto/grpc/testing/services.proto for package 'grpc.testing'
+# Source: src/proto/grpc/testing/worker_service.proto for package 'grpc.testing'
# Original file comments:
# Copyright 2015 gRPC authors.
#
@@ -19,29 +19,10 @@
# of unary/streaming requests/responses.
require 'grpc'
-require 'src/proto/grpc/testing/services_pb'
+require 'src/proto/grpc/testing/worker_service_pb'
module Grpc
module Testing
- module BenchmarkService
- class Service
-
- include GRPC::GenericService
-
- self.marshal_class_method = :encode
- self.unmarshal_class_method = :decode
- self.service_name = 'grpc.testing.BenchmarkService'
-
- # One request followed by one response.
- # The server returns the client payload as-is.
- rpc :UnaryCall, SimpleRequest, SimpleResponse
- # One request followed by one response.
- # The server returns the client payload as-is.
- rpc :StreamingCall, stream(SimpleRequest), stream(SimpleResponse)
- end
-
- Stub = Service.rpc_stub_class
- end
module WorkerService
class Service
diff --git a/src/ruby/qps/worker.rb b/src/ruby/qps/worker.rb
index 8258487..633ff13 100755
--- a/src/ruby/qps/worker.rb
+++ b/src/ruby/qps/worker.rb
@@ -29,7 +29,7 @@
require 'client'
require 'qps-common'
require 'server'
-require 'src/proto/grpc/testing/services_services_pb'
+require 'src/proto/grpc/testing/worker_service_services_pb'
class WorkerServiceImpl < Grpc::Testing::WorkerService::Service
def cpu_cores
diff --git a/src/ruby/spec/generic/client_stub_spec.rb b/src/ruby/spec/generic/client_stub_spec.rb
index d858c4e..da50f8d 100644
--- a/src/ruby/spec/generic/client_stub_spec.rb
+++ b/src/ruby/spec/generic/client_stub_spec.rb
@@ -750,6 +750,90 @@
expected_error_message)
end
end
+
+ # Prompted by grpc/github #14853
+ describe 'client-side error handling on bidi streams' do
+ class EnumeratorQueue
+ def initialize(queue)
+ @queue = queue
+ end
+
+ def each
+ loop do
+ msg = @queue.pop
+ break if msg.nil?
+ yield msg
+ end
+ end
+ end
+
+ def run_server_bidi_shutdown_after_one_read
+ @server.start
+ recvd_rpc = @server.request_call
+ recvd_call = recvd_rpc.call
+ server_call = GRPC::ActiveCall.new(
+ recvd_call, noop, noop, INFINITE_FUTURE,
+ metadata_received: true, started: false)
+ expect(server_call.remote_read).to eq('first message')
+ @server.shutdown_and_notify(from_relative_time(0))
+ @server.close
+ end
+
+ it 'receives a grpc status code when writes to a bidi stream fail' do
+ # This test tries to trigger the case when a 'SEND_MESSAGE' op
+ # and subseqeunt 'SEND_CLOSE_FROM_CLIENT' op of a bidi stream fails.
+ # In this case, iteration through the response stream should result
+ # in a grpc status code, and the writer thread should not raise an
+ # exception.
+ server_thread = Thread.new do
+ run_server_bidi_shutdown_after_one_read
+ end
+ stub = GRPC::ClientStub.new(@host, :this_channel_is_insecure)
+ request_queue = Queue.new
+ @sent_msgs = EnumeratorQueue.new(request_queue)
+ responses = get_responses(stub)
+ request_queue.push('first message')
+ # Now wait for the server to shut down.
+ server_thread.join
+ # Sanity check. This test is not interesting if
+ # Thread.abort_on_exception is not set.
+ expect(Thread.abort_on_exception).to be(true)
+ # An attempt to send a second message should fail now that the
+ # server is down.
+ request_queue.push('second message')
+ request_queue.push(nil)
+ expect { responses.next }.to raise_error(GRPC::BadStatus)
+ end
+
+ def run_server_bidi_shutdown_after_one_write
+ @server.start
+ recvd_rpc = @server.request_call
+ recvd_call = recvd_rpc.call
+ server_call = GRPC::ActiveCall.new(
+ recvd_call, noop, noop, INFINITE_FUTURE,
+ metadata_received: true, started: false)
+ server_call.send_initial_metadata
+ server_call.remote_send('message')
+ @server.shutdown_and_notify(from_relative_time(0))
+ @server.close
+ end
+
+ it 'receives a grpc status code when reading from a failed bidi call' do
+ server_thread = Thread.new do
+ run_server_bidi_shutdown_after_one_write
+ end
+ stub = GRPC::ClientStub.new(@host, :this_channel_is_insecure)
+ request_queue = Queue.new
+ @sent_msgs = EnumeratorQueue.new(request_queue)
+ responses = get_responses(stub)
+ expect(responses.next).to eq('message')
+ # Wait for the server to shut down
+ server_thread.join
+ expect { responses.next }.to raise_error(GRPC::BadStatus)
+ # Push a sentinel to allow the writer thread to finish
+ request_queue.push(nil)
+ end
+ end
end
describe 'without a call operation' do
@@ -810,6 +894,55 @@
responses.each { |r| p r }
end
end
+
+ def run_server_bidi_expect_client_to_cancel(wait_for_shutdown_ok_callback)
+ @server.start
+ recvd_rpc = @server.request_call
+ recvd_call = recvd_rpc.call
+ server_call = GRPC::ActiveCall.new(
+ recvd_call, noop, noop, INFINITE_FUTURE,
+ metadata_received: true, started: false)
+ server_call.send_initial_metadata
+ server_call.remote_send('server call received')
+ wait_for_shutdown_ok_callback.call
+ # since the client is cancelling the call,
+ # we should be able to shut down cleanly
+ @server.shutdown_and_notify(nil)
+ @server.close
+ end
+
+ it 'receives a grpc status code when reading from a cancelled bidi call' do
+ # This test tries to trigger a 'RECV_INITIAL_METADATA' and/or
+ # 'RECV_MESSAGE' op failure.
+ # An attempt to read a message might fail; in that case, iteration
+ # through the response stream should still result in a grpc status.
+ server_can_shutdown = false
+ server_can_shutdown_mu = Mutex.new
+ server_can_shutdown_cv = ConditionVariable.new
+ wait_for_shutdown_ok_callback = proc do
+ server_can_shutdown_mu.synchronize do
+ server_can_shutdown_cv.wait(server_can_shutdown_mu) until server_can_shutdown
+ end
+ end
+ server_thread = Thread.new do
+ run_server_bidi_expect_client_to_cancel(wait_for_shutdown_ok_callback)
+ end
+ stub = GRPC::ClientStub.new(@host, :this_channel_is_insecure)
+ request_queue = Queue.new
+ @sent_msgs = EnumeratorQueue.new(request_queue)
+ responses = get_responses(stub)
+ expect(responses.next).to eq('server call received')
+ @op.cancel
+ expect { responses.next }.to raise_error(GRPC::Cancelled)
+ # Now let the server proceed to shut down.
+ server_can_shutdown_mu.synchronize do
+ server_can_shutdown = true
+ server_can_shutdown_cv.broadcast
+ end
+ server_thread.join
+ # Push a sentinel to allow the writer thread to finish
+ request_queue.push(nil)
+ end
end
end
diff --git a/src/ruby/spec/pb/package_with_underscore/checker_spec.rb b/src/ruby/spec/pb/package_with_underscore/checker_spec.rb
new file mode 100644
index 0000000..dac7c14
--- /dev/null
+++ b/src/ruby/spec/pb/package_with_underscore/checker_spec.rb
@@ -0,0 +1,51 @@
+# 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.
+
+require 'open3'
+require 'tmpdir'
+
+describe 'Package with underscore protobuf code generation' do
+ it 'should have the same content as created by code generation' do
+ root_dir = File.join(File.dirname(__FILE__), '..', '..', '..', '..', '..')
+ pb_dir = File.join(root_dir, 'src', 'ruby', 'spec', 'pb')
+
+ fail 'CONFIG env variable unexpectedly unset' unless ENV['CONFIG']
+ bins_sub_dir = ENV['CONFIG']
+ bins_dir = File.join(root_dir, 'bins', bins_sub_dir)
+
+ plugin = File.join(bins_dir, 'grpc_ruby_plugin')
+ protoc = File.join(bins_dir, 'protobuf', 'protoc')
+
+ got = nil
+
+ Dir.mktmpdir do |tmp_dir|
+ gen_out = File.join(tmp_dir, 'package_with_underscore', 'service_services_pb.rb')
+
+ pid = spawn(
+ protoc,
+ '-I.',
+ 'package_with_underscore/service.proto',
+ "--grpc_out=#{tmp_dir}",
+ "--plugin=protoc-gen-grpc=#{plugin}",
+ chdir: pb_dir)
+ Process.waitpid2(pid)
+ File.open(gen_out) { |f| got = f.read }
+ end
+
+ correct_modularized_rpc = 'rpc :TestOne, ' \
+ 'Grpc::Testing::PackageWithUnderscore::Data::Request, ' \
+ 'Grpc::Testing::PackageWithUnderscore::Data::Response'
+ expect(got).to include(correct_modularized_rpc)
+ end
+end
diff --git a/src/ruby/spec/pb/package_with_underscore/data.proto b/src/ruby/spec/pb/package_with_underscore/data.proto
new file mode 100644
index 0000000..2706f1d
--- /dev/null
+++ b/src/ruby/spec/pb/package_with_underscore/data.proto
@@ -0,0 +1,23 @@
+// Copyright 2018 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.
+
+syntax = "proto3";
+
+package grpc.testing.package_with_underscore.data;
+
+message Request {
+}
+
+message Response {
+}
diff --git a/src/ruby/spec/pb/package_with_underscore/service.proto b/src/ruby/spec/pb/package_with_underscore/service.proto
new file mode 100644
index 0000000..814c789
--- /dev/null
+++ b/src/ruby/spec/pb/package_with_underscore/service.proto
@@ -0,0 +1,23 @@
+// Copyright 2018 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.
+
+syntax = "proto3";
+
+package grpc.testing.package_with_underscore.service;
+
+import "package_with_underscore/data.proto";
+
+service MyService {
+ rpc TestOne(data.Request) returns (data.Response) {}
+}
diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb
index 8dc1623..09d5c82 100644
--- a/src/ruby/tools/version.rb
+++ b/src/ruby/tools/version.rb
@@ -14,6 +14,6 @@
module GRPC
module Tools
- VERSION = '1.11.0.dev'
+ VERSION = '1.13.0.dev'
end
end
diff --git a/templates/CMakeLists.txt.template b/templates/CMakeLists.txt.template
index 01fe569..06adb33 100644
--- a/templates/CMakeLists.txt.template
+++ b/templates/CMakeLists.txt.template
@@ -82,6 +82,7 @@
set(gRPC_INSTALL_LIBDIR "lib" CACHE STRING "Installation directory for libraries")
set(gRPC_INSTALL_INCLUDEDIR "include" CACHE STRING "Installation directory for headers")
set(gRPC_INSTALL_CMAKEDIR "lib/cmake/<%text>${PACKAGE_NAME}</%text>" CACHE STRING "Installation directory for cmake config files")
+ set(gRPC_INSTALL_SHAREDIR "share/grpc" CACHE STRING "Installation directory for root certificates")
# Options
option(gRPC_BUILD_TESTS "Build tests" OFF)
@@ -298,11 +299,13 @@
endif (gRPC_BUILD_TESTS)
% else:
${cc_library(lib)}
+ % if not lib.build in ["tool"]:
${cc_install(lib)}
% endif
% endif
% endif
% endif
+ % endif
% endfor
% for tgt in targets:
@@ -323,7 +326,9 @@
% else:
${get_platforms_condition_begin(tgt.platforms)}\
${cc_binary(tgt)}
+ % if not tgt.build in ["tool"]:
${cc_install(tgt)}
+ % endif
${get_platforms_condition_end(tgt.platforms)}\
% endif
% endif
@@ -503,3 +508,6 @@
DESTINATION <%text>${gRPC_INSTALL_CMAKEDIR}</%text>
)
endforeach()
+
+ install(FILES <%text>${CMAKE_CURRENT_SOURCE_DIR}/etc/roots.pem</%text>
+ DESTINATION <%text>${gRPC_INSTALL_SHAREDIR}</%text>)
diff --git a/templates/Makefile.template b/templates/Makefile.template
index c0ce2e5..354f2a2 100644
--- a/templates/Makefile.template
+++ b/templates/Makefile.template
@@ -416,7 +416,7 @@
OPENSSL_ALPN_CHECK_CMD = $(PKG_CONFIG) --atleast-version=1.0.2 openssl
OPENSSL_NPN_CHECK_CMD = $(PKG_CONFIG) --atleast-version=1.0.1 openssl
ZLIB_CHECK_CMD = $(PKG_CONFIG) --exists zlib
- PROTOBUF_CHECK_CMD = $(PKG_CONFIG) --atleast-version=3.0.0 protobuf
+ PROTOBUF_CHECK_CMD = $(PKG_CONFIG) --atleast-version=3.5.0 protobuf
CARES_CHECK_CMD = $(PKG_CONFIG) --atleast-version=1.11.0 libcares
else # HAS_PKG_CONFIG
@@ -844,7 +844,7 @@
@echo
@echo "DEPENDENCY ERROR"
@echo
- @echo "The target you are trying to run requires protobuf 3.0.0+"
+ @echo "The target you are trying to run requires protobuf 3.5.0+"
@echo "Your system doesn't have it, and neither does the third_party directory."
@echo
@echo "Please consult INSTALL to get more information."
@@ -858,7 +858,7 @@
@echo
@echo "DEPENDENCY ERROR"
@echo
- @echo "The target you are trying to run requires protobuf-compiler 3.0.0+"
+ @echo "The target you are trying to run requires protobuf-compiler 3.5.0+"
@echo "Your system doesn't have it, and neither does the third_party directory."
@echo
@echo "Please consult INSTALL to get more information."
@@ -1636,7 +1636,7 @@
% endif
% if lib.language == 'c++':
## If the lib was C++, we have to close the Makefile's if that tested
- ## the presence of protobuf 3.0.0+
+ ## the presence of protobuf 3.5.0+
endif
% endif
@@ -1702,7 +1702,7 @@
ifeq ($(NO_PROTOBUF),true)
- # You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+ # You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/${tgt.name}: protobuf_dep_error
diff --git a/templates/config.m4.template b/templates/config.m4.template
index 9877e4b..cc19d98 100644
--- a/templates/config.m4.template
+++ b/templates/config.m4.template
@@ -10,6 +10,7 @@
PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/include)
PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/src/php/ext/grpc)
PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/third_party/boringssl/include)
+ PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/third_party/address_sorting/include)
LIBS="-lpthread $LIBS"
diff --git a/templates/config.w32.template b/templates/config.w32.template
index 4edef96..ef25e55 100644
--- a/templates/config.w32.template
+++ b/templates/config.w32.template
@@ -23,11 +23,13 @@
EXTENSION("grpc", grpc_source, null,
"/DOPENSSL_NO_ASM /D_GNU_SOURCE /DWIN32_LEAN_AND_MEAN "+
"/D_HAS_EXCEPTIONS=0 /DNOMINMAX /DGRPC_ARES=0 /D_WIN32_WINNT=0x600 "+
+ "/DPB_FIELD_16BIT "+
"/I"+configure_module_dirname+" "+
"/I"+configure_module_dirname+"\\include "+
"/I"+configure_module_dirname+"\\src\\php\\ext\\grpc "+
"/I"+configure_module_dirname+"\\third_party\\boringssl\\include "+
- "/I"+configure_module_dirname+"\\third_party\\zlib");
+ "/I"+configure_module_dirname+"\\third_party\\zlib "+
+ "/I"+configure_module_dirname+"\\third_party\\address_sorting\\include");
<%
dirs = {}
for lib in libs:
diff --git a/templates/gRPC-Core.podspec.template b/templates/gRPC-Core.podspec.template
index 33a8a8b..af97d81 100644
--- a/templates/gRPC-Core.podspec.template
+++ b/templates/gRPC-Core.podspec.template
@@ -42,21 +42,21 @@
out = grpc_lib_files(libs, ("grpc", "gpr"), ("headers",))
return [file for file in out if not file.startswith("third_party/nanopb/")]
- def grpc_cronet_private_files(libs):
- out = grpc_lib_files(libs, ("grpc_cronet", "gpr"), ("headers", "src"))
- excl = [
- # We do not want dummy cronet API for ObjC
+ def grpc_cronet_files(libs):
+ out = grpc_lib_files(libs, ("grpc_cronet",), ("src", "headers"))
+ excl = grpc_private_files(libs)
+ excl += [
+ # We do not need cronet dedicated plugin registry
+ "src/core/plugin_registry/grpc_cronet_plugin_registry.cc",
+ # We do not need dummy cronet API for ObjC
"src/core/ext/transport/cronet/transport/cronet_api_dummy.cc",
]
return [file for file in out if not file in excl]
def grpc_cronet_public_headers(libs):
- out = grpc_lib_files(libs, ("grpc_cronet", "gpr"), ("public_headers",))
- return out
-
- def grpc_cronet_private_headers(libs):
- out = grpc_lib_files(libs, ("grpc_cronet", "gpr"), ("headers",))
- return out
+ out = grpc_lib_files(libs, ("grpc_cronet",), ("public_headers",))
+ excl = grpc_public_headers(libs)
+ return [file for file in out if not file in excl]
def grpc_test_util_files(libs):
out = grpc_lib_files(libs, ("grpc_test_util", "gpr_test_util"), ("src", "headers"))
@@ -169,6 +169,7 @@
ss.dependency 'BoringSSL', '~> 10.0'
ss.dependency 'nanopb', '~> 0.3'
+ # To save you from scrolling, this is the last part of the podspec.
ss.source_files = ${ruby_multiline_list(grpc_private_files(libs), 22)}
ss.private_header_files = ${ruby_multiline_list(grpc_private_headers(libs), 30)}
@@ -181,21 +182,19 @@
s.subspec 'Cronet-Implementation' do |ss|
ss.header_mappings_dir = '.'
- ss.libraries = 'z'
+
+ ss.dependency "#{s.name}/Interface", version
+ ss.dependency "#{s.name}/Implementation", version
ss.dependency "#{s.name}/Cronet-Interface", version
- ss.dependency 'BoringSSL', '~> 10.0'
- ss.dependency 'nanopb', '~> 0.3'
- ss.source_files = ${ruby_multiline_list(grpc_cronet_private_files(libs), 22)}
-
- ss.private_header_files = ${ruby_multiline_list(grpc_cronet_private_headers(libs), 30)}
+ ss.source_files = ${ruby_multiline_list(grpc_cronet_files(libs), 22)}
end
- s.subspec 'Cronet-Tests' do |ss|
+ s.subspec 'Tests' do |ss|
ss.header_mappings_dir = '.'
- ss.dependency "#{s.name}/Cronet-Interface", version
- ss.dependency "#{s.name}/Cronet-Implementation", version
+ ss.dependency "#{s.name}/Interface", version
+ ss.dependency "#{s.name}/Implementation", version
ss.source_files = ${ruby_multiline_list(grpc_test_util_files(libs), 22)},
${ruby_multiline_list(end2end_tests_files(libs), 22)}
diff --git a/templates/src/csharp/Grpc.Core/Version.csproj.include.template b/templates/src/csharp/Grpc.Core/Version.csproj.include.template
index 5bc66e9..398b198 100755
--- a/templates/src/csharp/Grpc.Core/Version.csproj.include.template
+++ b/templates/src/csharp/Grpc.Core/Version.csproj.include.template
@@ -4,6 +4,6 @@
<Project>
<PropertyGroup>
<GrpcCsharpVersion>${settings.csharp_version}</GrpcCsharpVersion>
- <GoogleProtobufVersion>3.3.0</GoogleProtobufVersion>
+ <GoogleProtobufVersion>3.5.1</GoogleProtobufVersion>
</PropertyGroup>
</Project>
diff --git a/templates/src/objective-c/GRPCClient/private/version.h.template b/templates/src/objective-c/GRPCClient/private/version.h.template
index 34df24c..22b3bb2 100644
--- a/templates/src/objective-c/GRPCClient/private/version.h.template
+++ b/templates/src/objective-c/GRPCClient/private/version.h.template
@@ -24,5 +24,4 @@
// instead. This file can be regenerated from the template by running
// `tools/buildgen/generate_projects.sh`.
-
#define GRPC_OBJC_VERSION_STRING @"${settings.version}"
diff --git a/templates/src/objective-c/tests/version.h.template b/templates/src/objective-c/tests/version.h.template
index 72774ab..a87d43a 100644
--- a/templates/src/objective-c/tests/version.h.template
+++ b/templates/src/objective-c/tests/version.h.template
@@ -24,6 +24,5 @@
// instead. This file can be regenerated from the template by running
// `tools/buildgen/generate_projects.sh`.
-
#define GRPC_OBJC_VERSION_STRING @"${settings.version}"
#define GRPC_C_VERSION_STRING @"${settings.core_version}"
diff --git a/templates/test/cpp/naming/resolver_component_tests_defs.include b/templates/test/cpp/naming/resolver_component_tests_defs.include
index 01e1860..2690af4 100644
--- a/templates/test/cpp/naming/resolver_component_tests_defs.include
+++ b/templates/test/cpp/naming/resolver_component_tests_defs.include
@@ -1,4 +1,4 @@
-<%def name="resolver_component_tests(tests)">#!/bin/bash
+<%def name="resolver_component_tests(tests)">#!/usr/bin/env python
# Copyright 2015 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,80 +15,129 @@
# This file is auto-generated
-set -ex
+import argparse
+import sys
+import subprocess
+import tempfile
+import os
+import time
+import signal
-# all command args required in this set order
-FLAGS_test_bin_path=$(echo "$1" | grep '\--test_bin_path=' | sed 's/^--test_bin_path=//')
-FLAGS_dns_server_bin_path=$(echo "$2" | grep '\--dns_server_bin_path=' | sed 's/^--dns_server_bin_path=//')
-FLAGS_records_config_path=$(echo "$3" | grep '\--records_config_path=' | sed 's/^--records_config_path=//')
-FLAGS_dns_server_port=$(echo "$4" | grep '\--dns_server_port=' | sed 's/^--dns_server_port=//')
-FLAGS_dns_resolver_bin_path=$(echo "$5" | grep '\--dns_resolver_bin_path=' | sed 's/^--dns_resolver_bin_path=//')
-FLAGS_tcp_connect_bin_path=$(echo "$6" | grep '\--tcp_connect_bin_path=' | sed 's/^--tcp_connect_bin_path=//')
-for cmd_arg in "$FLAGS_test_bin_path" "$FLAGS_dns_server_bin_path" "$FLAGS_records_config_path" "$FLAGS_dns_server_port" "$FLAGS_dns_resolver_bin_path" "$FLAGS_tcp_connect_bin_path"; do
- if [[ "$cmd_arg" == "" ]]; then
- echo "Missing a CMD arg" && exit 1
- fi
-done
+argp = argparse.ArgumentParser(description='Run c-ares resolver tests')
+argp.add_argument('--test_bin_path', default=None, type=str,
+ help='Path to gtest test binary to invoke.')
+argp.add_argument('--dns_server_bin_path', default=None, type=str,
+ help='Path to local DNS server python script.')
+argp.add_argument('--records_config_path', default=None, type=str,
+ help=('Path to DNS records yaml file that '
+ 'specifies records for the DNS sever. '))
+argp.add_argument('--dns_server_port', default=None, type=int,
+ help=('Port that local DNS server is listening on.'))
+argp.add_argument('--dns_resolver_bin_path', default=None, type=str,
+ help=('Path to the DNS health check utility.'))
+argp.add_argument('--tcp_connect_bin_path', default=None, type=str,
+ help=('Path to the TCP health check utility.'))
+args = argp.parse_args()
-if [[ "$GRPC_DNS_RESOLVER" != "" && "$GRPC_DNS_RESOLVER" != ares ]]; then
- echo "This test only works under GRPC_DNS_RESOLVER=ares. Have GRPC_DNS_RESOLVER=$GRPC_DNS_RESOLVER" && exit 1
-fi
-export GRPC_DNS_RESOLVER=ares
+def test_runner_log(msg):
+ sys.stderr.write('\n%s: %s\n' % (__file__, msg))
-"$FLAGS_dns_server_bin_path" --records_config_path="$FLAGS_records_config_path" --port="$FLAGS_dns_server_port" > /dev/null 2>&1 &
-DNS_SERVER_PID=$!
-echo "Local DNS server started. PID: $DNS_SERVER_PID"
+cur_resolver = os.environ.get('GRPC_DNS_RESOLVER')
+if cur_resolver and cur_resolver != 'ares':
+ test_runner_log(('WARNING: cur resolver set to %s. This set of tests '
+ 'needs to use GRPC_DNS_RESOLVER=ares.'))
+ test_runner_log('Exit 1 without running tests.')
+ sys.exit(1)
+os.environ.update({'GRPC_DNS_RESOLVER': 'ares'})
-# Health check local DNS server TCP and UDP ports
-for ((i=0;i<30;i++));
-do
- echo "Retry health-check local DNS server by attempting a DNS query and TCP handshake"
- RETRY=0
- $FLAGS_dns_resolver_bin_path -s 127.0.0.1 -p "$FLAGS_dns_server_port" -n health-check-local-dns-server-is-alive.resolver-tests.grpctestingexp. -t 1 | grep '123.123.123.123' || RETRY=1
- $FLAGS_tcp_connect_bin_path -s 127.0.0.1 -p "$FLAGS_dns_server_port" -t 1 || RETRY=1
- if [[ "$RETRY" == 0 ]]; then
- break
- fi;
- sleep 0.1
-done
+def wait_until_dns_server_is_up(args,
+ dns_server_subprocess,
+ dns_server_subprocess_output):
+ for i in range(0, 30):
+ test_runner_log('Health check: attempt to connect to DNS server over TCP.')
+ tcp_connect_subprocess = subprocess.Popen([
+ args.tcp_connect_bin_path,
+ '--server_host', '127.0.0.1',
+ '--server_port', str(args.dns_server_port),
+ '--timeout', str(1)])
+ tcp_connect_subprocess.communicate()
+ if tcp_connect_subprocess.returncode == 0:
+ test_runner_log(('Health check: attempt to make an A-record '
+ 'query to DNS server.'))
+ dns_resolver_subprocess = subprocess.Popen([
+ args.dns_resolver_bin_path,
+ '--qname', 'health-check-local-dns-server-is-alive.resolver-tests.grpctestingexp',
+ '--server_host', '127.0.0.1',
+ '--server_port', str(args.dns_server_port)],
+ stdout=subprocess.PIPE)
+ dns_resolver_stdout, _ = dns_resolver_subprocess.communicate()
+ if dns_resolver_subprocess.returncode == 0:
+ if '123.123.123.123' in dns_resolver_stdout:
+ test_runner_log(('DNS server is up! '
+ 'Successfully reached it over UDP and TCP.'))
+ return
+ time.sleep(0.1)
+ dns_server_subprocess.kill()
+ dns_server_subprocess.wait()
+ test_runner_log(('Failed to reach DNS server over TCP and/or UDP. '
+ 'Exitting without running tests.'))
+ test_runner_log('======= DNS server stdout '
+ '(merged stdout and stderr) =============')
+ with open(dns_server_subprocess_output, 'r') as l:
+ test_runner_log(l.read())
+ test_runner_log('======= end DNS server output=========')
+ sys.exit(1)
-if [[ $RETRY == 1 ]]; then
- echo "FAILED TO START LOCAL DNS SERVER"
- kill -SIGTERM "$DNS_SERVER_PID"
- wait
- exit 1
-fi
+dns_server_subprocess_output = tempfile.mktemp()
+with open(dns_server_subprocess_output, 'w') as l:
+ dns_server_subprocess = subprocess.Popen([
+ args.dns_server_bin_path,
+ '--port', str(args.dns_server_port),
+ '--records_config_path', args.records_config_path],
+ stdin=subprocess.PIPE,
+ stdout=l,
+ stderr=l)
-function terminate_all {
- echo "Received signal. Terminating $! and $DNS_SERVER_PID"
- kill -SIGTERM "$!" || true
- kill -SIGTERM "$DNS_SERVER_PID" || true
- wait
- exit 1
-}
+def _quit_on_signal(signum, _frame):
+ test_runner_log('Received signal: %d' % signum)
+ dns_server_subprocess.kill()
+ dns_server_subprocess.wait()
+ sys.exit(1)
-trap terminate_all SIGTERM SIGINT
-
-EXIT_CODE=0
-# TODO: this test should check for GCE residency and skip tests using _grpclb._tcp.* SRV records once GCE residency checks are made
-# in the resolver.
+signal.signal(signal.SIGINT, _quit_on_signal)
+signal.signal(signal.SIGTERM, _quit_on_signal)
+wait_until_dns_server_is_up(args,
+ dns_server_subprocess,
+ dns_server_subprocess_output)
+num_test_failures = 0
% for test in tests:
-$FLAGS_test_bin_path \\
+test_runner_log('Run test with target: %s' % '${test['target_name']}')\
- --target_name='${test['target_name']}' \\
+current_test_subprocess = subprocess.Popen([\
- --expected_addrs='${test['expected_addrs']}' \\
+ args.test_bin_path,\
- --expected_chosen_service_config='${test['expected_chosen_service_config']}' \\
+ '--target_name', '${test['target_name']}',\
- --expected_lb_policy='${test['expected_lb_policy']}' \\
+ '--expected_addrs', '${test['expected_addrs']}',\
- --local_dns_server_address="127.0.0.1:$FLAGS_dns_server_port" &
-wait "$!" || EXIT_CODE=1
+ '--expected_chosen_service_config', '${test['expected_chosen_service_config']}',\
+
+ '--expected_lb_policy', '${test['expected_lb_policy']}',\
+
+ '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])\
+
+current_test_subprocess.communicate()\
+
+if current_test_subprocess.returncode != 0:\
+
+ num_test_failures += 1
% endfor
-kill -SIGTERM "$DNS_SERVER_PID" || true
-wait
-exit $EXIT_CODE</%def>
+test_runner_log('now kill DNS server')
+dns_server_subprocess.kill()
+dns_server_subprocess.wait()
+test_runner_log('%d tests failed.' % num_test_failures)
+sys.exit(num_test_failures)</%def>
diff --git a/templates/test/cpp/naming/resolver_component_tests_runner.sh.template b/templates/test/cpp/naming/resolver_component_tests_runner.py.template
similarity index 100%
rename from templates/test/cpp/naming/resolver_component_tests_runner.sh.template
rename to templates/test/cpp/naming/resolver_component_tests_runner.py.template
diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_android_java/Dockerfile.template b/templates/tools/dockerfile/interoptest/grpc_interop_android_java/Dockerfile.template
deleted file mode 100644
index 1f6755e..0000000
--- a/templates/tools/dockerfile/interoptest/grpc_interop_android_java/Dockerfile.template
+++ /dev/null
@@ -1,80 +0,0 @@
-%YAML 1.2
---- |
- # 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.
-
- FROM debian:jessie
-
- # Install JDK 8 and Git
- RUN echo oracle-java8-installer shared/accepted-oracle-license-v1-1 select true | /usr/bin/debconf-set-selections && ${'\\'}
- echo "deb http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main" | tee /etc/apt/sources.list.d/webupd8team-java.list && ${'\\'}
- echo "deb-src http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main" | tee -a /etc/apt/sources.list.d/webupd8team-java.list && ${'\\'}
- apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys EEA14886
- RUN apt-get update && apt-get -y install ${'\\'}
- git ${'\\'}
- libapr1 ${'\\'}
- oracle-java8-installer ${'\\'}
- && ${'\\'}
- apt-get clean && rm -r /var/cache/oracle-jdk8-installer/
- ENV JAVA_HOME /usr/lib/jvm/java-8-oracle
- ENV PATH $PATH:$JAVA_HOME/bin
-
- # Install protobuf
- RUN apt-get update && apt-get install -y ${'\\'}
- autoconf ${'\\'}
- build-essential ${'\\'}
- curl ${'\\'}
- gcc ${'\\'}
- libtool ${'\\'}
- unzip ${'\\'}
- && ${'\\'}
- apt-get clean
- WORKDIR /
- RUN git clone https://github.com/google/protobuf.git
- WORKDIR /protobuf
- RUN git checkout v3.3.1 && ${'\\'}
- ./autogen.sh && ${'\\'}
- ./configure && ${'\\'}
- make && ${'\\'}
- make check && ${'\\'}
- make install
-
- # Install gcloud command line tools
- ENV CLOUD_SDK_REPO "cloud-sdk-jessie"
- RUN echo "deb http://packages.cloud.google.com/apt $CLOUD_SDK_REPO main" | tee -a /etc/apt/sources.list.d/google-cloud-sdk.list && ${'\\'}
- curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - && ${'\\'}
- apt-get update && apt-get install -y google-cloud-sdk && apt-get clean && ${'\\'}
- gcloud config set component_manager/disable_update_check true
-
- # Install Android SDK
- WORKDIR /
- RUN mkdir android-sdk
- WORKDIR android-sdk
- RUN wget -q https://dl.google.com/android/repository/tools_r25.2.5-linux.zip && ${'\\'}
- unzip -qq tools_r25.2.5-linux.zip && ${'\\'}
- rm tools_r25.2.5-linux.zip && ${'\\'}
- echo y | tools/bin/sdkmanager "platforms;android-22" && ${'\\'}
- echo y | tools/bin/sdkmanager "build-tools;25.0.2" && ${'\\'}
- echo y | tools/bin/sdkmanager "extras;android;m2repository" && ${'\\'}
- echo y | tools/bin/sdkmanager "extras;google;google_play_services" && ${'\\'}
- echo y | tools/bin/sdkmanager "extras;google;m2repository" && ${'\\'}
- echo y | tools/bin/sdkmanager "patcher;v4" && ${'\\'}
- echo y | tools/bin/sdkmanager "platform-tools"
- ENV ANDROID_HOME "/android-sdk"
-
- # Reset the working directory
- WORKDIR /
-
- # Define the default command.
- CMD ["bash"]
diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile.template b/templates/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile.template
index f5a53f0..bf28796 100644
--- a/templates/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile.template
+++ b/templates/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile.template
@@ -18,6 +18,10 @@
<%include file="../../apt_get_basic.include"/>
<%include file="../../python_deps.include"/>
+ # Install pip and virtualenv for Python 3.4
+ RUN curl https://bootstrap.pypa.io/get-pip.py | python3.4
+ RUN python3.4 -m pip install virtualenv
+
<%include file="../../run_tests_addons.include"/>
# Define the default command.
CMD ["bash"]
diff --git a/templates/tools/dockerfile/python_deps.include b/templates/tools/dockerfile/python_deps.include
index cd1af22..c7bf238 100644
--- a/templates/tools/dockerfile/python_deps.include
+++ b/templates/tools/dockerfile/python_deps.include
@@ -9,6 +9,6 @@
python-pip
# Install Python packages from PyPI
-RUN pip install --upgrade pip==9.0.1
+RUN pip install --upgrade pip==10.0.1
RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.0.post1 six==1.10.0 twisted==17.5.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 twisted==17.5.0
diff --git a/templates/tools/dockerfile/test/cxx_alpine_x64/Dockerfile.template b/templates/tools/dockerfile/test/cxx_alpine_x64/Dockerfile.template
index 1bbfdfd..d70ad94 100644
--- a/templates/tools/dockerfile/test/cxx_alpine_x64/Dockerfile.template
+++ b/templates/tools/dockerfile/test/cxx_alpine_x64/Dockerfile.template
@@ -34,12 +34,13 @@
strace ${'\\'}
python-dev ${'\\'}
py-pip ${'\\'}
+ py-yaml ${'\\'}
unzip ${'\\'}
wget ${'\\'}
zip
# Install Python packages from PyPI
- RUN pip install --upgrade pip==9.0.1
+ RUN pip install --upgrade pip==10.0.1
RUN pip install virtualenv
RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.0.post1 six==1.10.0 twisted==17.5.0
diff --git a/templates/tools/dockerfile/test/multilang_jessie_x64/Dockerfile.template b/templates/tools/dockerfile/test/multilang_jessie_x64/Dockerfile.template
index 0d47aa9..672e9fb 100644
--- a/templates/tools/dockerfile/test/multilang_jessie_x64/Dockerfile.template
+++ b/templates/tools/dockerfile/test/multilang_jessie_x64/Dockerfile.template
@@ -25,6 +25,10 @@
<%include file="../../php_deps.include"/>
<%include file="../../ruby_deps.include"/>
<%include file="../../python_deps.include"/>
+ # Install pip and virtualenv for Python 3.4
+ RUN curl https://bootstrap.pypa.io/get-pip.py | python3.4
+ RUN python3.4 -m pip install virtualenv
+
# Install coverage for Python test coverage reporting
RUN pip install coverage
ENV PATH ~/.local/bin:$PATH
diff --git a/templates/tools/dockerfile/test/python_jessie_x64/Dockerfile.template b/templates/tools/dockerfile/test/python_jessie_x64/Dockerfile.template
index dba6a22..e73b839 100644
--- a/templates/tools/dockerfile/test/python_jessie_x64/Dockerfile.template
+++ b/templates/tools/dockerfile/test/python_jessie_x64/Dockerfile.template
@@ -19,6 +19,10 @@
<%include file="../../apt_get_basic.include"/>
<%include file="../../gcp_api_libraries.include"/>
<%include file="../../python_deps.include"/>
+ # Install pip and virtualenv for Python 3.4
+ RUN curl https://bootstrap.pypa.io/get-pip.py | python3.4
+ RUN python3.4 -m pip install virtualenv
+
<%include file="../../run_tests_addons.include"/>
# Define the default command.
CMD ["bash"]
diff --git a/templates/tools/dockerfile/test/python_pyenv_x64/Dockerfile.template b/templates/tools/dockerfile/test/python_pyenv_x64/Dockerfile.template
index 0df19f6..ba65c06 100644
--- a/templates/tools/dockerfile/test/python_pyenv_x64/Dockerfile.template
+++ b/templates/tools/dockerfile/test/python_pyenv_x64/Dockerfile.template
@@ -20,6 +20,10 @@
<%include file="../../gcp_api_libraries.include"/>
<%include file="../../python_deps.include"/>
<%include file="../../apt_get_pyenv.include"/>
+ # Install pip and virtualenv for Python 3.4
+ RUN curl https://bootstrap.pypa.io/get-pip.py | python3.4
+ RUN python3.4 -m pip install virtualenv
+
<%include file="../../run_tests_addons.include"/>
# Define the default command.
CMD ["bash"]
diff --git a/test/core/channel/minimal_stack_is_minimal_test.cc b/test/core/channel/minimal_stack_is_minimal_test.cc
index f02c818..e5953ac 100644
--- a/test/core/channel/minimal_stack_is_minimal_test.cc
+++ b/test/core/channel/minimal_stack_is_minimal_test.cc
@@ -66,35 +66,37 @@
minimal_stack_arg.key = const_cast<char*>(GRPC_ARG_MINIMAL_STACK);
minimal_stack_arg.value.integer = 1;
grpc_channel_args minimal_stack_args = {1, &minimal_stack_arg};
- errors += CHECK_STACK("unknown", &minimal_stack_args,
- GRPC_CLIENT_DIRECT_CHANNEL, "connected", NULL);
+ errors +=
+ CHECK_STACK("unknown", &minimal_stack_args, GRPC_CLIENT_DIRECT_CHANNEL,
+ "authority", "connected", NULL);
errors += CHECK_STACK("unknown", &minimal_stack_args, GRPC_CLIENT_SUBCHANNEL,
- "connected", NULL);
+ "authority", "connected", NULL);
errors += CHECK_STACK("unknown", &minimal_stack_args, GRPC_SERVER_CHANNEL,
"server", "connected", NULL);
errors +=
CHECK_STACK("chttp2", &minimal_stack_args, GRPC_CLIENT_DIRECT_CHANNEL,
- "http-client", "connected", NULL);
+ "authority", "http-client", "connected", NULL);
errors += CHECK_STACK("chttp2", &minimal_stack_args, GRPC_CLIENT_SUBCHANNEL,
- "http-client", "connected", NULL);
+ "authority", "http-client", "connected", NULL);
errors += CHECK_STACK("chttp2", &minimal_stack_args, GRPC_SERVER_CHANNEL,
"server", "http-server", "connected", NULL);
errors += CHECK_STACK(nullptr, &minimal_stack_args, GRPC_CLIENT_CHANNEL,
"client-channel", NULL);
// tests with a default stack
- errors += CHECK_STACK("unknown", nullptr, GRPC_CLIENT_DIRECT_CHANNEL,
- "message_size", "deadline", "connected", NULL);
- errors += CHECK_STACK("unknown", nullptr, GRPC_CLIENT_SUBCHANNEL,
+ errors +=
+ CHECK_STACK("unknown", nullptr, GRPC_CLIENT_DIRECT_CHANNEL, "authority",
+ "message_size", "deadline", "connected", NULL);
+ errors += CHECK_STACK("unknown", nullptr, GRPC_CLIENT_SUBCHANNEL, "authority",
"message_size", "connected", NULL);
errors += CHECK_STACK("unknown", nullptr, GRPC_SERVER_CHANNEL, "server",
"message_size", "deadline", "connected", NULL);
errors += CHECK_STACK("chttp2", nullptr, GRPC_CLIENT_DIRECT_CHANNEL,
- "message_size", "deadline", "http-client",
+ "authority", "message_size", "deadline", "http-client",
"message_compress", "connected", NULL);
- errors +=
- CHECK_STACK("chttp2", nullptr, GRPC_CLIENT_SUBCHANNEL, "message_size",
- "http-client", "message_compress", "connected", NULL);
+ errors += CHECK_STACK("chttp2", nullptr, GRPC_CLIENT_SUBCHANNEL, "authority",
+ "message_size", "http-client", "message_compress",
+ "connected", NULL);
errors += CHECK_STACK("chttp2", nullptr, GRPC_SERVER_CHANNEL, "server",
"message_size", "deadline", "http-server",
"message_compress", "connected", NULL);
diff --git a/test/core/client_channel/BUILD b/test/core/client_channel/BUILD
index 5148dc5..db98ffa 100644
--- a/test/core/client_channel/BUILD
+++ b/test/core/client_channel/BUILD
@@ -53,3 +53,18 @@
"//test/core/util:grpc_test_util",
],
)
+
+grpc_cc_test(
+ name = "retry_throttle_test",
+ srcs = ["retry_throttle_test.cc"],
+ external_deps = [
+ "gtest",
+ ],
+ language = "C++",
+ deps = [
+ "//:gpr",
+ "//:grpc",
+ "//test/core/util:gpr_test_util",
+ "//test/core/util:grpc_test_util",
+ ],
+)
diff --git a/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc b/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc
index 01c61a9..37e1d71 100644
--- a/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc
+++ b/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc
@@ -145,7 +145,6 @@
grpc_core::OrphanablePtr<grpc_core::Resolver> resolver;
grpc_channel_args* result = nullptr;
grpc_millis delay_before_second_resolution = 0;
- bool using_cares = false;
};
// Counter for the number of times a resolution notification callback has been
@@ -155,81 +154,100 @@
// Set to true by the last callback in the resolution chain.
bool g_all_callbacks_invoked;
-void on_third_resolution(void* arg, grpc_error* error) {
+void on_fourth_resolution(void* arg, grpc_error* error) {
OnResolutionCallbackArg* cb_arg = static_cast<OnResolutionCallbackArg*>(arg);
+ grpc_channel_args_destroy(cb_arg->result);
GPR_ASSERT(error == GRPC_ERROR_NONE);
++g_on_resolution_invocations_count;
- grpc_channel_args_destroy(cb_arg->result);
gpr_log(GPR_INFO,
- "3rd: g_on_resolution_invocations_count: %d, g_resolution_count: %d",
+ "4th: g_on_resolution_invocations_count: %d, g_resolution_count: %d",
g_on_resolution_invocations_count, g_resolution_count);
// In this case we expect to have incurred in another system-level resolution
- // because on_second_resolution slept for longer than the min resolution
+ // because on_third_resolution slept for longer than the min resolution
// period.
- GPR_ASSERT(g_on_resolution_invocations_count == 3);
- GPR_ASSERT(g_resolution_count == 2);
+ GPR_ASSERT(g_on_resolution_invocations_count == 4);
+ GPR_ASSERT(g_resolution_count == 3);
cb_arg->resolver.reset();
- if (cb_arg->using_cares) {
- gpr_atm_rel_store(&g_iomgr_args.done_atm, 1);
- gpr_mu_lock(g_iomgr_args.mu);
- GRPC_LOG_IF_ERROR("pollset_kick",
- grpc_pollset_kick(g_iomgr_args.pollset, nullptr));
- gpr_mu_unlock(g_iomgr_args.mu);
- }
+ gpr_atm_rel_store(&g_iomgr_args.done_atm, 1);
+ gpr_mu_lock(g_iomgr_args.mu);
+ GRPC_LOG_IF_ERROR("pollset_kick",
+ grpc_pollset_kick(g_iomgr_args.pollset, nullptr));
+ gpr_mu_unlock(g_iomgr_args.mu);
grpc_core::Delete(cb_arg);
g_all_callbacks_invoked = true;
}
+void on_third_resolution(void* arg, grpc_error* error) {
+ OnResolutionCallbackArg* cb_arg = static_cast<OnResolutionCallbackArg*>(arg);
+ grpc_channel_args_destroy(cb_arg->result);
+ GPR_ASSERT(error == GRPC_ERROR_NONE);
+ ++g_on_resolution_invocations_count;
+ gpr_log(GPR_INFO,
+ "3rd: g_on_resolution_invocations_count: %d, g_resolution_count: %d",
+ g_on_resolution_invocations_count, g_resolution_count);
+ // The timer set because of the previous re-resolution request fires, so a new
+ // system-level resolution happened.
+ GPR_ASSERT(g_on_resolution_invocations_count == 3);
+ GPR_ASSERT(g_resolution_count == 2);
+ grpc_core::ExecCtx::Get()->TestOnlySetNow(
+ cb_arg->delay_before_second_resolution * 2);
+ cb_arg->resolver->NextLocked(
+ &cb_arg->result,
+ GRPC_CLOSURE_CREATE(on_fourth_resolution, arg,
+ grpc_combiner_scheduler(g_combiner)));
+ cb_arg->resolver->RequestReresolutionLocked();
+ gpr_mu_lock(g_iomgr_args.mu);
+ GRPC_LOG_IF_ERROR("pollset_kick",
+ grpc_pollset_kick(g_iomgr_args.pollset, nullptr));
+ gpr_mu_unlock(g_iomgr_args.mu);
+}
+
void on_second_resolution(void* arg, grpc_error* error) {
OnResolutionCallbackArg* cb_arg = static_cast<OnResolutionCallbackArg*>(arg);
- ++g_on_resolution_invocations_count;
grpc_channel_args_destroy(cb_arg->result);
-
+ GPR_ASSERT(error == GRPC_ERROR_NONE);
+ ++g_on_resolution_invocations_count;
gpr_log(GPR_INFO,
"2nd: g_on_resolution_invocations_count: %d, g_resolution_count: %d",
g_on_resolution_invocations_count, g_resolution_count);
// The resolution request for which this function is the callback happened
// before the min resolution period. Therefore, no new system-level
- // resolutions happened, as indicated by g_resolution_count.
+ // resolutions happened, as indicated by g_resolution_count. But a resolution
+ // timer was set to fire when the cooldown finishes.
GPR_ASSERT(g_on_resolution_invocations_count == 2);
GPR_ASSERT(g_resolution_count == 1);
- grpc_core::ExecCtx::Get()->TestOnlySetNow(
- cb_arg->delay_before_second_resolution * 2);
+ // Register a new callback to capture the timer firing.
cb_arg->resolver->NextLocked(
&cb_arg->result,
GRPC_CLOSURE_CREATE(on_third_resolution, arg,
grpc_combiner_scheduler(g_combiner)));
- cb_arg->resolver->RequestReresolutionLocked();
- if (cb_arg->using_cares) {
- gpr_mu_lock(g_iomgr_args.mu);
- GRPC_LOG_IF_ERROR("pollset_kick",
- grpc_pollset_kick(g_iomgr_args.pollset, nullptr));
- gpr_mu_unlock(g_iomgr_args.mu);
- }
+ gpr_mu_lock(g_iomgr_args.mu);
+ GRPC_LOG_IF_ERROR("pollset_kick",
+ grpc_pollset_kick(g_iomgr_args.pollset, nullptr));
+ gpr_mu_unlock(g_iomgr_args.mu);
}
void on_first_resolution(void* arg, grpc_error* error) {
OnResolutionCallbackArg* cb_arg = static_cast<OnResolutionCallbackArg*>(arg);
- ++g_on_resolution_invocations_count;
grpc_channel_args_destroy(cb_arg->result);
+ GPR_ASSERT(error == GRPC_ERROR_NONE);
+ ++g_on_resolution_invocations_count;
+ gpr_log(GPR_INFO,
+ "1st: g_on_resolution_invocations_count: %d, g_resolution_count: %d",
+ g_on_resolution_invocations_count, g_resolution_count);
+ // There's one initial system-level resolution and one invocation of a
+ // notification callback (the current function).
+ GPR_ASSERT(g_on_resolution_invocations_count == 1);
+ GPR_ASSERT(g_resolution_count == 1);
cb_arg->resolver->NextLocked(
&cb_arg->result,
GRPC_CLOSURE_CREATE(on_second_resolution, arg,
grpc_combiner_scheduler(g_combiner)));
cb_arg->resolver->RequestReresolutionLocked();
- gpr_log(GPR_INFO,
- "1st: g_on_resolution_invocations_count: %d, g_resolution_count: %d",
- g_on_resolution_invocations_count, g_resolution_count);
- // Theres one initial system-level resolution and one invocation of a
- // notification callback (the current function).
- GPR_ASSERT(g_on_resolution_invocations_count == 1);
- GPR_ASSERT(g_resolution_count == 1);
- if (cb_arg->using_cares) {
- gpr_mu_lock(g_iomgr_args.mu);
- GRPC_LOG_IF_ERROR("pollset_kick",
- grpc_pollset_kick(g_iomgr_args.pollset, nullptr));
- gpr_mu_unlock(g_iomgr_args.mu);
- }
+ gpr_mu_lock(g_iomgr_args.mu);
+ GRPC_LOG_IF_ERROR("pollset_kick",
+ grpc_pollset_kick(g_iomgr_args.pollset, nullptr));
+ gpr_mu_unlock(g_iomgr_args.mu);
}
static void start_test_under_combiner(void* arg, grpc_error* error) {
@@ -269,22 +287,19 @@
grpc_uri_destroy(uri);
}
-static void test_cooldown(bool using_cares) {
+static void test_cooldown() {
grpc_core::ExecCtx exec_ctx;
- if (using_cares) iomgr_args_init(&g_iomgr_args);
+ iomgr_args_init(&g_iomgr_args);
OnResolutionCallbackArg* res_cb_arg =
grpc_core::New<OnResolutionCallbackArg>();
res_cb_arg->uri_str = "dns:127.0.0.1";
- res_cb_arg->using_cares = using_cares;
GRPC_CLOSURE_SCHED(GRPC_CLOSURE_CREATE(start_test_under_combiner, res_cb_arg,
grpc_combiner_scheduler(g_combiner)),
GRPC_ERROR_NONE);
- if (using_cares) {
- grpc_core::ExecCtx::Get()->Flush();
- poll_pollset_until_request_done(&g_iomgr_args);
- iomgr_args_finish(&g_iomgr_args);
- }
+ grpc_core::ExecCtx::Get()->Flush();
+ poll_pollset_until_request_done(&g_iomgr_args);
+ iomgr_args_finish(&g_iomgr_args);
}
int main(int argc, char** argv) {
@@ -293,16 +308,12 @@
g_combiner = grpc_combiner_create();
- bool using_cares = false;
-#if GRPC_ARES == 1
- using_cares = true;
-#endif
g_default_dns_lookup_ares = grpc_dns_lookup_ares;
grpc_dns_lookup_ares = test_dns_lookup_ares;
default_resolve_address = grpc_resolve_address_impl;
grpc_set_resolver_impl(&test_resolver);
- test_cooldown(using_cares);
+ test_cooldown();
{
grpc_core::ExecCtx exec_ctx;
diff --git a/test/core/client_channel/resolvers/dns_resolver_test.cc b/test/core/client_channel/resolvers/dns_resolver_test.cc
index e3fba28..103b291 100644
--- a/test/core/client_channel/resolvers/dns_resolver_test.cc
+++ b/test/core/client_channel/resolvers/dns_resolver_test.cc
@@ -70,11 +70,12 @@
test_succeeds(dns, "dns:10.2.1.1");
test_succeeds(dns, "dns:10.2.1.1:1234");
- test_succeeds(dns, "ipv4:www.google.com");
+ test_succeeds(dns, "dns:www.google.com");
+ test_succeeds(dns, "dns:///www.google.com");
if (grpc_resolve_address == grpc_resolve_address_ares) {
- test_succeeds(dns, "ipv4://8.8.8.8/8.8.8.8:8888");
+ test_succeeds(dns, "dns://8.8.8.8/8.8.8.8:8888");
} else {
- test_fails(dns, "ipv4://8.8.8.8/8.8.8.8:8888");
+ test_fails(dns, "dns://8.8.8.8/8.8.8.8:8888");
}
{
diff --git a/test/core/client_channel/retry_throttle_test.cc b/test/core/client_channel/retry_throttle_test.cc
new file mode 100644
index 0000000..c6d5d3e
--- /dev/null
+++ b/test/core/client_channel/retry_throttle_test.cc
@@ -0,0 +1,142 @@
+/*
+ *
+ * Copyright 2018 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.
+ *
+ */
+
+#include "src/core/ext/filters/client_channel/retry_throttle.h"
+
+#include <gtest/gtest.h>
+
+#include "test/core/util/test_config.h"
+
+namespace grpc_core {
+namespace internal {
+namespace {
+
+TEST(ServerRetryThrottleData, Basic) {
+ // Max token count is 4, so threshold for retrying is 2.
+ // Token count starts at 4.
+ // Each failure decrements by 1. Each success increments by 1.6.
+ auto throttle_data =
+ MakeRefCounted<ServerRetryThrottleData>(4000, 1600, nullptr);
+ // Failure: token_count=3. Above threshold.
+ EXPECT_TRUE(throttle_data->RecordFailure());
+ // Success: token_count=4. Not incremented beyond max.
+ throttle_data->RecordSuccess();
+ // Failure: token_count=3. Above threshold.
+ EXPECT_TRUE(throttle_data->RecordFailure());
+ // Failure: token_count=2. At threshold, so no retries.
+ EXPECT_FALSE(throttle_data->RecordFailure());
+ // Failure: token_count=1. Below threshold, so no retries.
+ EXPECT_FALSE(throttle_data->RecordFailure());
+ // Failure: token_count=0. Below threshold, so no retries.
+ EXPECT_FALSE(throttle_data->RecordFailure());
+ // Failure: token_count=0. Below threshold, so no retries. Not
+ // decremented below min.
+ EXPECT_FALSE(throttle_data->RecordFailure());
+ // Success: token_count=1.6.
+ throttle_data->RecordSuccess();
+ // Success: token_count=3.2.
+ throttle_data->RecordSuccess();
+ // Failure: token_count=2.2. Above threshold.
+ EXPECT_TRUE(throttle_data->RecordFailure());
+ // Failure: token_count=1.2. Below threshold, so no retries.
+ EXPECT_FALSE(throttle_data->RecordFailure());
+ // Success: token_count=2.8.
+ throttle_data->RecordSuccess();
+ // Failure: token_count=1.8. Below threshold, so no retries.
+ EXPECT_FALSE(throttle_data->RecordFailure());
+ // Success: token_count=3.4.
+ throttle_data->RecordSuccess();
+ // Failure: token_count=2.4. Above threshold.
+ EXPECT_TRUE(throttle_data->RecordFailure());
+}
+
+TEST(ServerRetryThrottleData, Replacement) {
+ // Create old throttle data.
+ // Max token count is 4, so threshold for retrying is 2.
+ // Token count starts at 4.
+ // Each failure decrements by 1. Each success increments by 1.
+ auto old_throttle_data =
+ MakeRefCounted<ServerRetryThrottleData>(4000, 1000, nullptr);
+ // Failure: token_count=3. Above threshold.
+ EXPECT_TRUE(old_throttle_data->RecordFailure());
+ // Create new throttle data.
+ // Max token count is 10, so threshold for retrying is 5.
+ // Token count starts at 7.5 (ratio inherited from old_throttle_data).
+ // Each failure decrements by 1. Each success increments by 3.
+ auto throttle_data = MakeRefCounted<ServerRetryThrottleData>(
+ 10000, 3000, old_throttle_data.get());
+ // Failure via old_throttle_data: token_count=6.5.
+ EXPECT_TRUE(old_throttle_data->RecordFailure());
+ // Failure: token_count=5.5.
+ EXPECT_TRUE(old_throttle_data->RecordFailure());
+ // Failure via old_throttle_data: token_count=4.5. Below threshold.
+ EXPECT_FALSE(old_throttle_data->RecordFailure());
+ // Failure: token_count=3.5. Below threshold.
+ EXPECT_FALSE(throttle_data->RecordFailure());
+ // Success: token_count=6.5.
+ throttle_data->RecordSuccess();
+ // Failure via old_throttle_data: token_count=5.5. Above threshold.
+ EXPECT_TRUE(old_throttle_data->RecordFailure());
+ // Failure: token_count=4.5. Below threshold.
+ EXPECT_FALSE(throttle_data->RecordFailure());
+}
+
+TEST(ServerRetryThrottleMap, Replacement) {
+ ServerRetryThrottleMap::Init();
+ const char kServerName[] = "server_name";
+ // Create old throttle data.
+ // Max token count is 4, so threshold for retrying is 2.
+ // Token count starts at 4.
+ // Each failure decrements by 1. Each success increments by 1.
+ auto old_throttle_data =
+ ServerRetryThrottleMap::GetDataForServer(kServerName, 4000, 1000);
+ // Failure: token_count=3. Above threshold.
+ EXPECT_TRUE(old_throttle_data->RecordFailure());
+ // Create new throttle data.
+ // Max token count is 10, so threshold for retrying is 5.
+ // Token count starts at 7.5 (ratio inherited from old_throttle_data).
+ // Each failure decrements by 1. Each success increments by 3.
+ auto throttle_data =
+ ServerRetryThrottleMap::GetDataForServer(kServerName, 10000, 3000);
+ // Failure via old_throttle_data: token_count=6.5.
+ EXPECT_TRUE(old_throttle_data->RecordFailure());
+ // Failure: token_count=5.5.
+ EXPECT_TRUE(old_throttle_data->RecordFailure());
+ // Failure via old_throttle_data: token_count=4.5. Below threshold.
+ EXPECT_FALSE(old_throttle_data->RecordFailure());
+ // Failure: token_count=3.5. Below threshold.
+ EXPECT_FALSE(throttle_data->RecordFailure());
+ // Success: token_count=6.5.
+ throttle_data->RecordSuccess();
+ // Failure via old_throttle_data: token_count=5.5. Above threshold.
+ EXPECT_TRUE(old_throttle_data->RecordFailure());
+ // Failure: token_count=4.5. Below threshold.
+ EXPECT_FALSE(throttle_data->RecordFailure());
+ // Clean up.
+ ServerRetryThrottleMap::Shutdown();
+}
+
+} // namespace
+} // namespace internal
+} // namespace grpc_core
+
+int main(int argc, char** argv) {
+ grpc_test_init(argc, argv);
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/test/core/end2end/end2end_nosec_tests.cc b/test/core/end2end/end2end_nosec_tests.cc
index 78ddcdb..59eb643 100644
--- a/test/core/end2end/end2end_nosec_tests.cc
+++ b/test/core/end2end/end2end_nosec_tests.cc
@@ -38,6 +38,8 @@
extern void bad_ping_pre_init(void);
extern void binary_metadata(grpc_end2end_test_config config);
extern void binary_metadata_pre_init(void);
+extern void call_host_override(grpc_end2end_test_config config);
+extern void call_host_override_pre_init(void);
extern void cancel_after_accept(grpc_end2end_test_config config);
extern void cancel_after_accept_pre_init(void);
extern void cancel_after_client_done(grpc_end2end_test_config config);
@@ -130,6 +132,8 @@
extern void retry_exceeds_buffer_size_in_subsequent_batch_pre_init(void);
extern void retry_non_retriable_status(grpc_end2end_test_config config);
extern void retry_non_retriable_status_pre_init(void);
+extern void retry_non_retriable_status_before_recv_trailing_metadata_started(grpc_end2end_test_config config);
+extern void retry_non_retriable_status_before_recv_trailing_metadata_started_pre_init(void);
extern void retry_recv_initial_metadata(grpc_end2end_test_config config);
extern void retry_recv_initial_metadata_pre_init(void);
extern void retry_recv_message(grpc_end2end_test_config config);
@@ -187,6 +191,7 @@
bad_hostname_pre_init();
bad_ping_pre_init();
binary_metadata_pre_init();
+ call_host_override_pre_init();
cancel_after_accept_pre_init();
cancel_after_client_done_pre_init();
cancel_after_invoke_pre_init();
@@ -233,6 +238,7 @@
retry_exceeds_buffer_size_in_initial_batch_pre_init();
retry_exceeds_buffer_size_in_subsequent_batch_pre_init();
retry_non_retriable_status_pre_init();
+ retry_non_retriable_status_before_recv_trailing_metadata_started_pre_init();
retry_recv_initial_metadata_pre_init();
retry_recv_message_pre_init();
retry_server_pushback_delay_pre_init();
@@ -270,6 +276,7 @@
bad_hostname(config);
bad_ping(config);
binary_metadata(config);
+ call_host_override(config);
cancel_after_accept(config);
cancel_after_client_done(config);
cancel_after_invoke(config);
@@ -316,6 +323,7 @@
retry_exceeds_buffer_size_in_initial_batch(config);
retry_exceeds_buffer_size_in_subsequent_batch(config);
retry_non_retriable_status(config);
+ retry_non_retriable_status_before_recv_trailing_metadata_started(config);
retry_recv_initial_metadata(config);
retry_recv_message(config);
retry_server_pushback_delay(config);
@@ -360,6 +368,10 @@
binary_metadata(config);
continue;
}
+ if (0 == strcmp("call_host_override", argv[i])) {
+ call_host_override(config);
+ continue;
+ }
if (0 == strcmp("cancel_after_accept", argv[i])) {
cancel_after_accept(config);
continue;
@@ -544,6 +556,10 @@
retry_non_retriable_status(config);
continue;
}
+ if (0 == strcmp("retry_non_retriable_status_before_recv_trailing_metadata_started", argv[i])) {
+ retry_non_retriable_status_before_recv_trailing_metadata_started(config);
+ continue;
+ }
if (0 == strcmp("retry_recv_initial_metadata", argv[i])) {
retry_recv_initial_metadata(config);
continue;
diff --git a/test/core/end2end/end2end_tests.cc b/test/core/end2end/end2end_tests.cc
index fb1e61b..9f164b4 100644
--- a/test/core/end2end/end2end_tests.cc
+++ b/test/core/end2end/end2end_tests.cc
@@ -40,6 +40,8 @@
extern void binary_metadata_pre_init(void);
extern void call_creds(grpc_end2end_test_config config);
extern void call_creds_pre_init(void);
+extern void call_host_override(grpc_end2end_test_config config);
+extern void call_host_override_pre_init(void);
extern void cancel_after_accept(grpc_end2end_test_config config);
extern void cancel_after_accept_pre_init(void);
extern void cancel_after_client_done(grpc_end2end_test_config config);
@@ -132,6 +134,8 @@
extern void retry_exceeds_buffer_size_in_subsequent_batch_pre_init(void);
extern void retry_non_retriable_status(grpc_end2end_test_config config);
extern void retry_non_retriable_status_pre_init(void);
+extern void retry_non_retriable_status_before_recv_trailing_metadata_started(grpc_end2end_test_config config);
+extern void retry_non_retriable_status_before_recv_trailing_metadata_started_pre_init(void);
extern void retry_recv_initial_metadata(grpc_end2end_test_config config);
extern void retry_recv_initial_metadata_pre_init(void);
extern void retry_recv_message(grpc_end2end_test_config config);
@@ -190,6 +194,7 @@
bad_ping_pre_init();
binary_metadata_pre_init();
call_creds_pre_init();
+ call_host_override_pre_init();
cancel_after_accept_pre_init();
cancel_after_client_done_pre_init();
cancel_after_invoke_pre_init();
@@ -236,6 +241,7 @@
retry_exceeds_buffer_size_in_initial_batch_pre_init();
retry_exceeds_buffer_size_in_subsequent_batch_pre_init();
retry_non_retriable_status_pre_init();
+ retry_non_retriable_status_before_recv_trailing_metadata_started_pre_init();
retry_recv_initial_metadata_pre_init();
retry_recv_message_pre_init();
retry_server_pushback_delay_pre_init();
@@ -274,6 +280,7 @@
bad_ping(config);
binary_metadata(config);
call_creds(config);
+ call_host_override(config);
cancel_after_accept(config);
cancel_after_client_done(config);
cancel_after_invoke(config);
@@ -320,6 +327,7 @@
retry_exceeds_buffer_size_in_initial_batch(config);
retry_exceeds_buffer_size_in_subsequent_batch(config);
retry_non_retriable_status(config);
+ retry_non_retriable_status_before_recv_trailing_metadata_started(config);
retry_recv_initial_metadata(config);
retry_recv_message(config);
retry_server_pushback_delay(config);
@@ -368,6 +376,10 @@
call_creds(config);
continue;
}
+ if (0 == strcmp("call_host_override", argv[i])) {
+ call_host_override(config);
+ continue;
+ }
if (0 == strcmp("cancel_after_accept", argv[i])) {
cancel_after_accept(config);
continue;
@@ -552,6 +564,10 @@
retry_non_retriable_status(config);
continue;
}
+ if (0 == strcmp("retry_non_retriable_status_before_recv_trailing_metadata_started", argv[i])) {
+ retry_non_retriable_status_before_recv_trailing_metadata_started(config);
+ continue;
+ }
if (0 == strcmp("retry_recv_initial_metadata", argv[i])) {
retry_recv_initial_metadata(config);
continue;
diff --git a/test/core/end2end/end2end_tests.h b/test/core/end2end/end2end_tests.h
index b42d90b..a1ebded 100644
--- a/test/core/end2end/end2end_tests.h
+++ b/test/core/end2end/end2end_tests.h
@@ -52,6 +52,11 @@
/* Which features are supported by this fixture. See feature flags above. */
uint32_t feature_mask;
+ /* If the call host is setup by the fixture (for example, via the
+ * GRPC_SSL_TARGET_NAME_OVERRIDE_ARG channel arg), which value should the test
+ * expect to find in call_details.host */
+ const char* overridden_call_host;
+
grpc_end2end_test_fixture (*create_fixture)(grpc_channel_args* client_args,
grpc_channel_args* server_args);
void (*init_client)(grpc_end2end_test_fixture* f,
diff --git a/test/core/end2end/fixtures/h2_census.cc b/test/core/end2end/fixtures/h2_census.cc
index b3b4171..29b1d6d 100644
--- a/test/core/end2end/fixtures/h2_census.cc
+++ b/test/core/end2end/fixtures/h2_census.cc
@@ -111,7 +111,7 @@
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER,
- chttp2_create_fixture_fullstack, chttp2_init_client_fullstack,
+ nullptr, chttp2_create_fixture_fullstack, chttp2_init_client_fullstack,
chttp2_init_server_fullstack, chttp2_tear_down_fullstack},
};
diff --git a/test/core/end2end/fixtures/h2_compress.cc b/test/core/end2end/fixtures/h2_compress.cc
index 565c96c..4aaadf7 100644
--- a/test/core/end2end/fixtures/h2_compress.cc
+++ b/test/core/end2end/fixtures/h2_compress.cc
@@ -109,7 +109,7 @@
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER,
- chttp2_create_fixture_fullstack_compression,
+ nullptr, chttp2_create_fixture_fullstack_compression,
chttp2_init_client_fullstack_compression,
chttp2_init_server_fullstack_compression,
chttp2_tear_down_fullstack_compression},
diff --git a/test/core/end2end/fixtures/h2_fakesec.cc b/test/core/end2end/fixtures/h2_fakesec.cc
index bbf65fc..a653d7c 100644
--- a/test/core/end2end/fixtures/h2_fakesec.cc
+++ b/test/core/end2end/fixtures/h2_fakesec.cc
@@ -132,10 +132,9 @@
static grpc_end2end_test_config configs[] = {
{"chttp2/fake_secure_fullstack",
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
- FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS |
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER,
- chttp2_create_fixture_secure_fullstack,
+ nullptr, chttp2_create_fixture_secure_fullstack,
chttp2_init_client_fake_secure_fullstack,
chttp2_init_server_fake_secure_fullstack,
chttp2_tear_down_secure_fullstack},
diff --git a/test/core/end2end/fixtures/h2_fd.cc b/test/core/end2end/fixtures/h2_fd.cc
index 9157ab0..52be0f7 100644
--- a/test/core/end2end/fixtures/h2_fd.cc
+++ b/test/core/end2end/fixtures/h2_fd.cc
@@ -96,7 +96,7 @@
/* All test configurations */
static grpc_end2end_test_config configs[] = {
- {"chttp2/fd", FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER,
+ {"chttp2/fd", FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER, nullptr,
chttp2_create_fixture_socketpair, chttp2_init_client_socketpair,
chttp2_init_server_socketpair, chttp2_tear_down_socketpair},
};
diff --git a/test/core/end2end/fixtures/h2_full+pipe.cc b/test/core/end2end/fixtures/h2_full+pipe.cc
index ed173c1..c532964 100644
--- a/test/core/end2end/fixtures/h2_full+pipe.cc
+++ b/test/core/end2end/fixtures/h2_full+pipe.cc
@@ -96,7 +96,7 @@
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER,
- chttp2_create_fixture_fullstack, chttp2_init_client_fullstack,
+ nullptr, chttp2_create_fixture_fullstack, chttp2_init_client_fullstack,
chttp2_init_server_fullstack, chttp2_tear_down_fullstack},
};
diff --git a/test/core/end2end/fixtures/h2_full+trace.cc b/test/core/end2end/fixtures/h2_full+trace.cc
index afb86ea..ba7a780 100644
--- a/test/core/end2end/fixtures/h2_full+trace.cc
+++ b/test/core/end2end/fixtures/h2_full+trace.cc
@@ -96,7 +96,7 @@
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER,
- chttp2_create_fixture_fullstack, chttp2_init_client_fullstack,
+ nullptr, chttp2_create_fixture_fullstack, chttp2_init_client_fullstack,
chttp2_init_server_fullstack, chttp2_tear_down_fullstack},
};
diff --git a/test/core/end2end/fixtures/h2_full+workarounds.cc b/test/core/end2end/fixtures/h2_full+workarounds.cc
index bd9ddff..78da841 100644
--- a/test/core/end2end/fixtures/h2_full+workarounds.cc
+++ b/test/core/end2end/fixtures/h2_full+workarounds.cc
@@ -107,7 +107,7 @@
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER |
FEATURE_MASK_SUPPORTS_WORKAROUNDS,
- chttp2_create_fixture_fullstack, chttp2_init_client_fullstack,
+ nullptr, chttp2_create_fixture_fullstack, chttp2_init_client_fullstack,
chttp2_init_server_fullstack, chttp2_tear_down_fullstack},
};
diff --git a/test/core/end2end/fixtures/h2_full.cc b/test/core/end2end/fixtures/h2_full.cc
index ca61ec8..0c826b6 100644
--- a/test/core/end2end/fixtures/h2_full.cc
+++ b/test/core/end2end/fixtures/h2_full.cc
@@ -90,7 +90,7 @@
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER,
- chttp2_create_fixture_fullstack, chttp2_init_client_fullstack,
+ nullptr, chttp2_create_fixture_fullstack, chttp2_init_client_fullstack,
chttp2_init_server_fullstack, chttp2_tear_down_fullstack},
};
diff --git a/test/core/end2end/fixtures/h2_http_proxy.cc b/test/core/end2end/fixtures/h2_http_proxy.cc
index 90d0627..0af8a29 100644
--- a/test/core/end2end/fixtures/h2_http_proxy.cc
+++ b/test/core/end2end/fixtures/h2_http_proxy.cc
@@ -113,7 +113,7 @@
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER,
- chttp2_create_fixture_fullstack, chttp2_init_client_fullstack,
+ nullptr, chttp2_create_fixture_fullstack, chttp2_init_client_fullstack,
chttp2_init_server_fullstack, chttp2_tear_down_fullstack},
};
diff --git a/test/core/end2end/fixtures/h2_load_reporting.cc b/test/core/end2end/fixtures/h2_load_reporting.cc
index ec9eedb..18ea10a 100644
--- a/test/core/end2end/fixtures/h2_load_reporting.cc
+++ b/test/core/end2end/fixtures/h2_load_reporting.cc
@@ -98,8 +98,9 @@
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER,
- chttp2_create_fixture_load_reporting, chttp2_init_client_load_reporting,
- chttp2_init_server_load_reporting, chttp2_tear_down_load_reporting},
+ nullptr, chttp2_create_fixture_load_reporting,
+ chttp2_init_client_load_reporting, chttp2_init_server_load_reporting,
+ chttp2_tear_down_load_reporting},
};
int main(int argc, char** argv) {
diff --git a/test/core/end2end/fixtures/h2_oauth2.cc b/test/core/end2end/fixtures/h2_oauth2.cc
index 9453f2f..d44aafd 100644
--- a/test/core/end2end/fixtures/h2_oauth2.cc
+++ b/test/core/end2end/fixtures/h2_oauth2.cc
@@ -216,7 +216,7 @@
FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS |
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER,
- chttp2_create_fixture_secure_fullstack,
+ "foo.test.google.fr", chttp2_create_fixture_secure_fullstack,
chttp2_init_client_simple_ssl_with_oauth2_secure_fullstack,
chttp2_init_server_simple_ssl_secure_fullstack,
chttp2_tear_down_secure_fullstack},
diff --git a/test/core/end2end/fixtures/h2_proxy.cc b/test/core/end2end/fixtures/h2_proxy.cc
index c97188f..a320000 100644
--- a/test/core/end2end/fixtures/h2_proxy.cc
+++ b/test/core/end2end/fixtures/h2_proxy.cc
@@ -117,7 +117,7 @@
FEATURE_MASK_SUPPORTS_REQUEST_PROXYING |
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER,
- chttp2_create_fixture_fullstack, chttp2_init_client_fullstack,
+ nullptr, chttp2_create_fixture_fullstack, chttp2_init_client_fullstack,
chttp2_init_server_fullstack, chttp2_tear_down_fullstack},
};
diff --git a/test/core/end2end/fixtures/h2_sockpair+trace.cc b/test/core/end2end/fixtures/h2_sockpair+trace.cc
index d539dda..cdefcf4 100644
--- a/test/core/end2end/fixtures/h2_sockpair+trace.cc
+++ b/test/core/end2end/fixtures/h2_sockpair+trace.cc
@@ -63,9 +63,14 @@
static void client_setup_transport(void* ts, grpc_transport* transport) {
sp_client_setup* cs = static_cast<sp_client_setup*>(ts);
-
- cs->f->client = grpc_channel_create("socketpair-target", cs->client_args,
+ grpc_arg authority_arg = grpc_channel_arg_string_create(
+ const_cast<char*>(GRPC_ARG_DEFAULT_AUTHORITY),
+ const_cast<char*>("test-authority"));
+ grpc_channel_args* args =
+ grpc_channel_args_copy_and_add(cs->client_args, &authority_arg, 1);
+ cs->f->client = grpc_channel_create("socketpair-target", args,
GRPC_CLIENT_DIRECT_CHANNEL, transport);
+ grpc_channel_args_destroy(args);
}
static grpc_end2end_test_fixture chttp2_create_fixture_socketpair(
@@ -118,7 +123,7 @@
/* All test configurations */
static grpc_end2end_test_config configs[] = {
- {"chttp2/socketpair", FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER,
+ {"chttp2/socketpair", FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER, nullptr,
chttp2_create_fixture_socketpair, chttp2_init_client_socketpair,
chttp2_init_server_socketpair, chttp2_tear_down_socketpair},
};
diff --git a/test/core/end2end/fixtures/h2_sockpair.cc b/test/core/end2end/fixtures/h2_sockpair.cc
index 75f6402..8966cb3 100644
--- a/test/core/end2end/fixtures/h2_sockpair.cc
+++ b/test/core/end2end/fixtures/h2_sockpair.cc
@@ -58,8 +58,14 @@
static void client_setup_transport(void* ts, grpc_transport* transport) {
sp_client_setup* cs = static_cast<sp_client_setup*>(ts);
- cs->f->client = grpc_channel_create("socketpair-target", cs->client_args,
+ grpc_arg authority_arg = grpc_channel_arg_string_create(
+ const_cast<char*>(GRPC_ARG_DEFAULT_AUTHORITY),
+ const_cast<char*>("test-authority"));
+ grpc_channel_args* args =
+ grpc_channel_args_copy_and_add(cs->client_args, &authority_arg, 1);
+ cs->f->client = grpc_channel_create("socketpair-target", args,
GRPC_CLIENT_DIRECT_CHANNEL, transport);
+ grpc_channel_args_destroy(args);
}
static grpc_end2end_test_fixture chttp2_create_fixture_socketpair(
@@ -112,7 +118,7 @@
/* All test configurations */
static grpc_end2end_test_config configs[] = {
- {"chttp2/socketpair", FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER,
+ {"chttp2/socketpair", FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER, nullptr,
chttp2_create_fixture_socketpair, chttp2_init_client_socketpair,
chttp2_init_server_socketpair, chttp2_tear_down_socketpair},
};
diff --git a/test/core/end2end/fixtures/h2_sockpair_1byte.cc b/test/core/end2end/fixtures/h2_sockpair_1byte.cc
index 9296319..ebf4162 100644
--- a/test/core/end2end/fixtures/h2_sockpair_1byte.cc
+++ b/test/core/end2end/fixtures/h2_sockpair_1byte.cc
@@ -58,8 +58,14 @@
static void client_setup_transport(void* ts, grpc_transport* transport) {
sp_client_setup* cs = static_cast<sp_client_setup*>(ts);
- cs->f->client = grpc_channel_create("socketpair-target", cs->client_args,
+ grpc_arg authority_arg = grpc_channel_arg_string_create(
+ const_cast<char*>(GRPC_ARG_DEFAULT_AUTHORITY),
+ const_cast<char*>("test-authority"));
+ grpc_channel_args* args =
+ grpc_channel_args_copy_and_add(cs->client_args, &authority_arg, 1);
+ cs->f->client = grpc_channel_create("socketpair-target", args,
GRPC_CLIENT_DIRECT_CHANNEL, transport);
+ grpc_channel_args_destroy(args);
}
static grpc_end2end_test_fixture chttp2_create_fixture_socketpair(
@@ -124,9 +130,9 @@
/* All test configurations */
static grpc_end2end_test_config configs[] = {
{"chttp2/socketpair_one_byte_at_a_time",
- FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER, chttp2_create_fixture_socketpair,
- chttp2_init_client_socketpair, chttp2_init_server_socketpair,
- chttp2_tear_down_socketpair},
+ FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER, nullptr,
+ chttp2_create_fixture_socketpair, chttp2_init_client_socketpair,
+ chttp2_init_server_socketpair, chttp2_tear_down_socketpair},
};
int main(int argc, char** argv) {
diff --git a/test/core/end2end/fixtures/h2_ssl.cc b/test/core/end2end/fixtures/h2_ssl.cc
index bbcc88e..999cd4c 100644
--- a/test/core/end2end/fixtures/h2_ssl.cc
+++ b/test/core/end2end/fixtures/h2_ssl.cc
@@ -109,10 +109,7 @@
grpc_channel_args* new_client_args =
grpc_channel_args_copy_and_add(client_args, &ssl_name_override, 1);
chttp2_init_client_secure_fullstack(f, new_client_args, ssl_creds);
- {
- grpc_core::ExecCtx exec_ctx;
- grpc_channel_args_destroy(new_client_args);
- }
+ grpc_channel_args_destroy(new_client_args);
}
static int fail_server_auth_check(grpc_channel_args* server_args) {
@@ -149,7 +146,7 @@
FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS |
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER,
- chttp2_create_fixture_secure_fullstack,
+ "foo.test.google.fr", chttp2_create_fixture_secure_fullstack,
chttp2_init_client_simple_ssl_secure_fullstack,
chttp2_init_server_simple_ssl_secure_fullstack,
chttp2_tear_down_secure_fullstack},
diff --git a/test/core/end2end/fixtures/h2_ssl_proxy.cc b/test/core/end2end/fixtures/h2_ssl_proxy.cc
index 6b0b891..9ab50c6 100644
--- a/test/core/end2end/fixtures/h2_ssl_proxy.cc
+++ b/test/core/end2end/fixtures/h2_ssl_proxy.cc
@@ -187,7 +187,7 @@
FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS |
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER,
- chttp2_create_fixture_secure_fullstack,
+ "foo.test.google.fr", chttp2_create_fixture_secure_fullstack,
chttp2_init_client_simple_ssl_secure_fullstack,
chttp2_init_server_simple_ssl_secure_fullstack,
chttp2_tear_down_secure_fullstack},
diff --git a/test/core/end2end/fixtures/h2_uds.cc b/test/core/end2end/fixtures/h2_uds.cc
index 1b081f9..2c81c3d 100644
--- a/test/core/end2end/fixtures/h2_uds.cc
+++ b/test/core/end2end/fixtures/h2_uds.cc
@@ -95,7 +95,7 @@
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER,
- chttp2_create_fixture_fullstack, chttp2_init_client_fullstack,
+ nullptr, chttp2_create_fixture_fullstack, chttp2_init_client_fullstack,
chttp2_init_server_fullstack, chttp2_tear_down_fullstack},
};
diff --git a/test/core/end2end/fixtures/inproc.cc b/test/core/end2end/fixtures/inproc.cc
index d47de42..be6eda8 100644
--- a/test/core/end2end/fixtures/inproc.cc
+++ b/test/core/end2end/fixtures/inproc.cc
@@ -75,8 +75,9 @@
/* All test configurations */
static grpc_end2end_test_config configs[] = {
- {"inproc", FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER, inproc_create_fixture,
- inproc_init_client, inproc_init_server, inproc_tear_down},
+ {"inproc", FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER, nullptr,
+ inproc_create_fixture, inproc_init_client, inproc_init_server,
+ inproc_tear_down},
};
int main(int argc, char** argv) {
diff --git a/test/core/end2end/fuzzers/api_fuzzer.cc b/test/core/end2end/fuzzers/api_fuzzer.cc
index 9ace7d0..36f257d 100644
--- a/test/core/end2end/fuzzers/api_fuzzer.cc
+++ b/test/core/end2end/fuzzers/api_fuzzer.cc
@@ -38,8 +38,14 @@
#include "src/core/lib/surface/server.h"
#include "src/core/lib/transport/metadata.h"
#include "test/core/end2end/data/ssl_test_data.h"
+#include "test/core/util/fuzzer_util.h"
#include "test/core/util/passthru_endpoint.h"
+using grpc_core::testing::grpc_fuzzer_get_next_byte;
+using grpc_core::testing::grpc_fuzzer_get_next_string;
+using grpc_core::testing::grpc_fuzzer_get_next_uint32;
+using grpc_core::testing::input_stream;
+
////////////////////////////////////////////////////////////////////////////////
// logging
@@ -65,58 +71,20 @@
return ts;
}
-////////////////////////////////////////////////////////////////////////////////
-// input_stream: allows easy access to input bytes, and allows reading a little
-// past the end (avoiding needing to check everywhere)
-
-typedef struct {
- const uint8_t* cur;
- const uint8_t* end;
-} input_stream;
-
-static uint8_t next_byte(input_stream* inp) {
- if (inp->cur == inp->end) {
- return 0;
- }
- return *inp->cur++;
-}
-
static void end(input_stream* inp) { inp->cur = inp->end; }
-static char* read_string(input_stream* inp, bool* special) {
- char* str = nullptr;
- size_t cap = 0;
- size_t sz = 0;
- char c;
- do {
- if (cap == sz) {
- cap = GPR_MAX(3 * cap / 2, cap + 8);
- str = static_cast<char*>(gpr_realloc(str, cap));
- }
- c = static_cast<char>(next_byte(inp));
- str[sz++] = c;
- } while (c != 0 && c != 1);
- if (special != nullptr) {
- *special = (c == 1);
- }
- if (c == 1) {
- str[sz - 1] = 0;
- }
- return str;
-}
-
static void read_buffer(input_stream* inp, char** buffer, size_t* length,
bool* special) {
- *length = next_byte(inp);
+ *length = grpc_fuzzer_get_next_byte(inp);
if (*length == 255) {
if (special != nullptr) *special = true;
- *length = next_byte(inp);
+ *length = grpc_fuzzer_get_next_byte(inp);
} else {
if (special != nullptr) *special = false;
}
*buffer = static_cast<char*>(gpr_malloc(*length));
for (size_t i = 0; i < *length; i++) {
- (*buffer)[i] = static_cast<char>(next_byte(inp));
+ (*buffer)[i] = static_cast<char>(grpc_fuzzer_get_next_byte(inp));
}
}
@@ -128,7 +96,7 @@
static grpc_slice read_string_like_slice(input_stream* inp) {
bool special;
- char* s = read_string(inp, &special);
+ char* s = grpc_fuzzer_get_next_string(inp, &special);
grpc_slice r = maybe_intern(grpc_slice_from_copied_string(s), special);
gpr_free(s);
return r;
@@ -146,39 +114,15 @@
}
static uint32_t read_uint22(input_stream* inp) {
- uint8_t b = next_byte(inp);
+ uint8_t b = grpc_fuzzer_get_next_byte(inp);
uint32_t x = b & 0x7f;
if (b & 0x80) {
x <<= 7;
- b = next_byte(inp);
+ b = grpc_fuzzer_get_next_byte(inp);
x |= b & 0x7f;
if (b & 0x80) {
x <<= 8;
- x |= next_byte(inp);
- }
- }
- return x;
-}
-
-static uint32_t read_uint32(input_stream* inp) {
- uint8_t b = next_byte(inp);
- uint32_t x = b & 0x7f;
- if (b & 0x80) {
- x <<= 7;
- b = next_byte(inp);
- x |= b & 0x7f;
- if (b & 0x80) {
- x <<= 7;
- b = next_byte(inp);
- x |= b & 0x7f;
- if (b & 0x80) {
- x <<= 7;
- b = next_byte(inp);
- x |= b & 0x7f;
- if (b & 0x80) {
- x = (x << 4) | (next_byte(inp) & 0x0f);
- }
- }
+ x |= grpc_fuzzer_get_next_byte(inp);
}
}
return x;
@@ -193,22 +137,22 @@
}
static int read_int(input_stream* inp) {
- return static_cast<int>(read_uint32(inp));
+ return static_cast<int>(grpc_fuzzer_get_next_uint32(inp));
}
static grpc_channel_args* read_args(input_stream* inp) {
- size_t n = next_byte(inp);
+ size_t n = grpc_fuzzer_get_next_byte(inp);
grpc_arg* args = static_cast<grpc_arg*>(gpr_malloc(sizeof(*args) * n));
for (size_t i = 0; i < n; i++) {
- switch (next_byte(inp)) {
+ switch (grpc_fuzzer_get_next_byte(inp)) {
case 1:
args[i].type = GRPC_ARG_STRING;
- args[i].key = read_string(inp, nullptr);
- args[i].value.string = read_string(inp, nullptr);
+ args[i].key = grpc_fuzzer_get_next_string(inp, nullptr);
+ args[i].value.string = grpc_fuzzer_get_next_string(inp, nullptr);
break;
case 2:
args[i].type = GRPC_ARG_INTEGER;
- args[i].key = read_string(inp, nullptr);
+ args[i].key = grpc_fuzzer_get_next_string(inp, nullptr);
args[i].value.integer = read_int(inp);
break;
case 3:
@@ -249,10 +193,11 @@
static const char* read_cred_artifact(cred_artifact_ctx* ctx, input_stream* inp,
const char** builtins,
size_t num_builtins) {
- uint8_t b = next_byte(inp);
+ uint8_t b = grpc_fuzzer_get_next_byte(inp);
if (b == 0) return nullptr;
if (b == 1)
- return ctx->release[ctx->num_release++] = read_string(inp, nullptr);
+ return ctx->release[ctx->num_release++] =
+ grpc_fuzzer_get_next_string(inp, nullptr);
if (b >= num_builtins + 1) {
end(inp);
return nullptr;
@@ -288,7 +233,7 @@
end(inp);
return nullptr;
}
- switch (next_byte(inp)) {
+ switch (grpc_fuzzer_get_next_byte(inp)) {
default:
end(inp);
return nullptr;
@@ -339,7 +284,7 @@
}
static grpc_channel_credentials* read_channel_creds(input_stream* inp) {
- switch (next_byte(inp)) {
+ switch (grpc_fuzzer_get_next_byte(inp)) {
case 0:
return read_ssl_channel_creds(inp);
break;
@@ -673,7 +618,7 @@
static void read_metadata(input_stream* inp, size_t* count,
grpc_metadata** metadata, call_state* cs) {
- *count = next_byte(inp);
+ *count = grpc_fuzzer_get_next_byte(inp);
if (*count) {
*metadata =
static_cast<grpc_metadata*>(gpr_malloc(*count * sizeof(**metadata)));
@@ -681,7 +626,7 @@
for (size_t i = 0; i < *count; i++) {
(*metadata)[i].key = read_string_like_slice(inp);
(*metadata)[i].value = read_buffer_like_slice(inp);
- (*metadata)[i].flags = read_uint32(inp);
+ (*metadata)[i].flags = grpc_fuzzer_get_next_uint32(inp);
add_slice_to_unref(cs, (*metadata)[i].key);
add_slice_to_unref(cs, (*metadata)[i].value);
}
@@ -811,7 +756,7 @@
grpc_timer_manager_tick();
- switch (next_byte(&inp)) {
+ switch (grpc_fuzzer_get_next_byte(&inp)) {
// terminate on bad bytes
default:
end(&inp);
@@ -838,13 +783,14 @@
// increment global time
case 1: {
g_now = gpr_time_add(
- g_now, gpr_time_from_micros(read_uint32(&inp), GPR_TIMESPAN));
+ g_now, gpr_time_from_micros(grpc_fuzzer_get_next_uint32(&inp),
+ GPR_TIMESPAN));
break;
}
// create an insecure channel
case 2: {
if (g_channel == nullptr) {
- char* target = read_string(&inp, nullptr);
+ char* target = grpc_fuzzer_get_next_string(&inp, nullptr);
char* target_uri;
gpr_asprintf(&target_uri, "dns:%s", target);
grpc_channel_args* args = read_args(&inp);
@@ -927,7 +873,7 @@
// check connectivity
case 8: {
if (g_channel != nullptr) {
- uint8_t try_to_connect = next_byte(&inp);
+ uint8_t try_to_connect = grpc_fuzzer_get_next_byte(&inp);
if (try_to_connect == 0 || try_to_connect == 1) {
grpc_channel_check_connectivity_state(g_channel, try_to_connect);
} else {
@@ -946,7 +892,8 @@
if (st != GRPC_CHANNEL_SHUTDOWN) {
gpr_timespec deadline = gpr_time_add(
gpr_now(GPR_CLOCK_REALTIME),
- gpr_time_from_micros(read_uint32(&inp), GPR_TIMESPAN));
+ gpr_time_from_micros(grpc_fuzzer_get_next_uint32(&inp),
+ GPR_TIMESPAN));
grpc_channel_watch_connectivity_state(
g_channel, st, deadline, cq,
create_validator(validate_connectivity_watch,
@@ -971,7 +918,7 @@
}
parent_call = g_active_call->call;
}
- uint32_t propagation_mask = read_uint32(&inp);
+ uint32_t propagation_mask = grpc_fuzzer_get_next_uint32(&inp);
grpc_slice method = read_string_like_slice(&inp);
if (GRPC_SLICE_LENGTH(method) == 0) {
ok = false;
@@ -979,7 +926,8 @@
grpc_slice host = read_string_like_slice(&inp);
gpr_timespec deadline =
gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
- gpr_time_from_micros(read_uint32(&inp), GPR_TIMESPAN));
+ gpr_time_from_micros(grpc_fuzzer_get_next_uint32(&inp),
+ GPR_TIMESPAN));
if (ok) {
call_state* cs = new_call(g_active_call, CLIENT);
@@ -1005,7 +953,7 @@
end(&inp);
break;
}
- size_t num_ops = next_byte(&inp);
+ size_t num_ops = grpc_fuzzer_get_next_byte(&inp);
if (num_ops > 6) {
end(&inp);
break;
@@ -1019,7 +967,7 @@
uint8_t has_ops = 0;
for (i = 0; i < num_ops; i++) {
op = &ops[i];
- switch (next_byte(&inp)) {
+ switch (grpc_fuzzer_get_next_byte(&inp)) {
default:
/* invalid value */
op->op = (grpc_op_type)-1;
@@ -1060,7 +1008,8 @@
&op->data.send_status_from_server.trailing_metadata,
g_active_call);
op->data.send_status_from_server.status =
- static_cast<grpc_status_code>(next_byte(&inp));
+ static_cast<grpc_status_code>(
+ grpc_fuzzer_get_next_byte(&inp));
op->data.send_status_from_server.status_details =
add_slice_to_unref(g_active_call,
read_buffer_like_slice(&inp));
@@ -1097,7 +1046,7 @@
break;
}
op->reserved = nullptr;
- op->flags = read_uint32(&inp);
+ op->flags = grpc_fuzzer_get_next_uint32(&inp);
}
if (ok) {
validator* v = make_finished_batch_validator(g_active_call, has_ops);
@@ -1160,14 +1109,14 @@
}
// enable a tracer
case 17: {
- char* tracer = read_string(&inp, nullptr);
+ char* tracer = grpc_fuzzer_get_next_string(&inp, nullptr);
grpc_tracer_set_enabled(tracer, 1);
gpr_free(tracer);
break;
}
// disable a tracer
case 18: {
- char* tracer = read_string(&inp, nullptr);
+ char* tracer = grpc_fuzzer_get_next_string(&inp, nullptr);
grpc_tracer_set_enabled(tracer, 0);
gpr_free(tracer);
break;
@@ -1209,7 +1158,7 @@
// create a secure channel
case 22: {
if (g_channel == nullptr) {
- char* target = read_string(&inp, nullptr);
+ char* target = grpc_fuzzer_get_next_string(&inp, nullptr);
char* target_uri;
gpr_asprintf(&target_uri, "dns:%s", target);
grpc_channel_args* args = read_args(&inp);
diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-api_fuzzer-5406804084260864 b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-api_fuzzer-5406804084260864
new file mode 100644
index 0000000..121aac7
--- /dev/null
+++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-api_fuzzer-5406804084260864
Binary files differ
diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-api_fuzzer-5471994809155584 b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-api_fuzzer-5471994809155584
new file mode 100644
index 0000000..e5d3d38
--- /dev/null
+++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-api_fuzzer-5471994809155584
Binary files differ
diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-api_fuzzer-6609852341157888 b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-api_fuzzer-6609852341157888
new file mode 100644
index 0000000..b7debab
--- /dev/null
+++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-api_fuzzer-6609852341157888
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer.cc b/test/core/end2end/fuzzers/client_fuzzer.cc
index 16acf8e..e21006b 100644
--- a/test/core/end2end/fuzzers/client_fuzzer.cc
+++ b/test/core/end2end/fuzzers/client_fuzzer.cc
@@ -20,6 +20,7 @@
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
+#include <grpc/support/string_util.h>
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "src/core/lib/iomgr/executor.h"
@@ -58,8 +59,14 @@
grpc_create_chttp2_transport(nullptr, mock_endpoint, true);
grpc_chttp2_transport_start_reading(transport, nullptr, nullptr);
+ grpc_arg authority_arg = grpc_channel_arg_string_create(
+ const_cast<char*>(GRPC_ARG_DEFAULT_AUTHORITY),
+ const_cast<char*>("test-authority"));
+ grpc_channel_args* args =
+ grpc_channel_args_copy_and_add(nullptr, &authority_arg, 1);
grpc_channel* channel = grpc_channel_create(
- "test-target", nullptr, GRPC_CLIENT_DIRECT_CHANNEL, transport);
+ "test-target", args, GRPC_CLIENT_DIRECT_CHANNEL, transport);
+ grpc_channel_args_destroy(args);
grpc_slice host = grpc_slice_from_static_string("localhost");
grpc_call* call = grpc_channel_create_call(
channel, nullptr, 0, cq, grpc_slice_from_static_string("/foo"), &host,
diff --git a/test/core/end2end/gen_build_yaml.py b/test/core/end2end/gen_build_yaml.py
index 4e20b0b..c355fc2 100755
--- a/test/core/end2end/gen_build_yaml.py
+++ b/test/core/end2end/gen_build_yaml.py
@@ -108,6 +108,8 @@
proxyable=False, cpu_cost=LOWCPU, exclude_iomgrs=['uv']),
'default_host': default_test_options._replace(
needs_fullstack=True, needs_dns=True, needs_names=True),
+ 'call_host_override': default_test_options._replace(
+ needs_fullstack=True, needs_dns=True, needs_names=True),
'disappearing_server': connectivity_test_options._replace(flaky=True,
needs_names=True),
'empty_batch': default_test_options._replace(cpu_cost=LOWCPU),
@@ -168,6 +170,9 @@
proxyable=False),
'retry_non_retriable_status': default_test_options._replace(
cpu_cost=LOWCPU, needs_client_channel=True, proxyable=False),
+ 'retry_non_retriable_status_before_recv_trailing_metadata_started':
+ default_test_options._replace(
+ cpu_cost=LOWCPU, needs_client_channel=True, proxyable=False),
'retry_recv_initial_metadata': default_test_options._replace(
cpu_cost=LOWCPU, needs_client_channel=True, proxyable=False),
'retry_recv_message': default_test_options._replace(
diff --git a/test/core/end2end/generate_tests.bzl b/test/core/end2end/generate_tests.bzl
index 8e723fd..11fc576 100755
--- a/test/core/end2end/generate_tests.bzl
+++ b/test/core/end2end/generate_tests.bzl
@@ -101,6 +101,8 @@
'binary_metadata': test_options(),
'resource_quota_server': test_options(proxyable=False),
'call_creds': test_options(secure=True),
+ 'call_host_override': test_options(needs_fullstack=True, needs_dns=True,
+ needs_names=True),
'cancel_after_accept': test_options(),
'cancel_after_client_done': test_options(),
'cancel_after_invoke': test_options(),
@@ -156,6 +158,8 @@
needs_client_channel=True, proxyable=False),
'retry_non_retriable_status': test_options(needs_client_channel=True,
proxyable=False),
+ 'retry_non_retriable_status_before_recv_trailing_metadata_started':
+ test_options(needs_client_channel=True, proxyable=False),
'retry_recv_initial_metadata': test_options(needs_client_channel=True,
proxyable=False),
'retry_recv_message': test_options(needs_client_channel=True,
diff --git a/test/core/end2end/h2_ssl_cert_test.cc b/test/core/end2end/h2_ssl_cert_test.cc
index 9e2082c..9ed6f23 100644
--- a/test/core/end2end/h2_ssl_cert_test.cc
+++ b/test/core/end2end/h2_ssl_cert_test.cc
@@ -57,8 +57,6 @@
f.fixture_data = ffd;
f.cq = grpc_completion_queue_create_for_next(nullptr);
- f.shutdown_cq = grpc_completion_queue_create_for_pluck(nullptr);
-
return f;
}
@@ -202,6 +200,7 @@
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION | \
FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS | \
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL, \
+ "foo.test.google.fr", \
chttp2_create_fixture_secure_fullstack, \
CLIENT_INIT_NAME(cert_type), \
SERVER_INIT_NAME(request_type), \
@@ -270,27 +269,13 @@
} while (ev.type != GRPC_QUEUE_SHUTDOWN);
}
+// Shuts down the server.
+// Side effect - Also shuts down and drains the completion queue.
static void shutdown_server(grpc_end2end_test_fixture* f) {
if (!f->server) return;
- /* Perform a completion queue next, so that any pending operations can be
- * finished, and resources can be released. This is so that, shutdown does not
- * hang. For example, the server might be stuck in the handshaking code, which
- * keeps a ref to a listener. Unless, it is unref'd, shutdown won't be able
- * to proceed.
- *
- * (If shutdown times out, it is probably because 100ms wasn't enough. In that
- * case, the deadline can be increased. Or, we could simply have another
- * thread for the server to poll the completion queue while the shutdown
- * progresses.)
- */
- GPR_ASSERT(grpc_completion_queue_next(
- f->cq, grpc_timeout_milliseconds_to_deadline(100), nullptr)
- .type == GRPC_QUEUE_TIMEOUT);
- grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
- GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
- grpc_timeout_seconds_to_deadline(5),
- nullptr)
- .type == GRPC_OP_COMPLETE);
+ grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
+ grpc_completion_queue_shutdown(f->cq);
+ drain_cq(f->cq);
grpc_server_destroy(f->server);
f->server = nullptr;
}
@@ -304,11 +289,7 @@
static void end_test(grpc_end2end_test_fixture* f) {
shutdown_client(f);
shutdown_server(f);
-
- grpc_completion_queue_shutdown(f->cq);
- drain_cq(f->cq);
grpc_completion_queue_destroy(f->cq);
- grpc_completion_queue_destroy(f->shutdown_cq);
}
static void simple_request_body(grpc_end2end_test_fixture f,
diff --git a/test/core/end2end/tests/bad_ping.cc b/test/core/end2end/tests/bad_ping.cc
index 239c608..98d893f 100644
--- a/test/core/end2end/tests/bad_ping.cc
+++ b/test/core/end2end/tests/bad_ping.cc
@@ -108,11 +108,9 @@
grpc_slice details;
int was_cancelled = 2;
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
@@ -207,8 +205,6 @@
// the in-progress RPC should fail.
GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE);
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(was_cancelled == 1);
grpc_slice_unref(details);
@@ -271,11 +267,9 @@
grpc_slice details;
int was_cancelled = 2;
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
@@ -361,6 +355,11 @@
grpc_server_shutdown_and_notify(f.server, f.cq, tag(0xdead));
CQ_EXPECT_COMPLETION(cqv, tag(0xdead), 1);
+
+ // Also expect the previously blocked pings to complete with an error
+ CQ_EXPECT_COMPLETION(cqv, tag(200 + MAX_PING_STRIKES + 1), 0);
+ CQ_EXPECT_COMPLETION(cqv, tag(200 + MAX_PING_STRIKES + 2), 0);
+
cq_verify(cqv);
grpc_call_unref(s);
@@ -368,8 +367,6 @@
// The rpc should be successful.
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
grpc_slice_unref(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
diff --git a/test/core/end2end/tests/binary_metadata.cc b/test/core/end2end/tests/binary_metadata.cc
index e66b4da..cdf5b1e 100644
--- a/test/core/end2end/tests/binary_metadata.cc
+++ b/test/core/end2end/tests/binary_metadata.cc
@@ -136,11 +136,9 @@
int was_cancelled = 2;
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
@@ -278,8 +276,6 @@
"\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0"
"\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(was_cancelled == 0);
GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, "hello world"));
GPR_ASSERT(byte_buffer_eq_string(response_payload_recv, "hello you"));
diff --git a/test/core/end2end/tests/call_creds.cc b/test/core/end2end/tests/call_creds.cc
index e9cbaa3..ead6ecb 100644
--- a/test/core/end2end/tests/call_creds.cc
+++ b/test/core/end2end/tests/call_creds.cc
@@ -156,11 +156,9 @@
cqv = cq_verifier_create(f.cq);
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
creds = grpc_google_iam_credentials_create(iam_token, iam_selector, nullptr);
GPR_ASSERT(creds != nullptr);
@@ -292,8 +290,6 @@
GPR_ASSERT(status == GRPC_STATUS_OK);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(was_cancelled == 0);
GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, "hello world"));
GPR_ASSERT(byte_buffer_eq_string(response_payload_recv, "hello you"));
@@ -396,11 +392,9 @@
f = begin_test(config, "test_request_with_server_rejecting_client_creds", 1);
cqv = cq_verifier_create(f.cq);
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
creds = grpc_google_iam_credentials_create(iam_token, iam_selector, nullptr);
diff --git a/test/core/end2end/tests/call_host_override.cc b/test/core/end2end/tests/call_host_override.cc
new file mode 100644
index 0000000..251dc6d
--- /dev/null
+++ b/test/core/end2end/tests/call_host_override.cc
@@ -0,0 +1,230 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#include "test/core/end2end/end2end_tests.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include <grpc/byte_buffer.h>
+#include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/time.h>
+
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gpr/string.h"
+#include "test/core/end2end/cq_verifier.h"
+
+static void* tag(intptr_t t) { return (void*)t; }
+
+static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
+ const char* test_name,
+ grpc_channel_args* client_args,
+ grpc_channel_args* server_args) {
+ grpc_end2end_test_fixture f;
+ gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name);
+ f = config.create_fixture(client_args, server_args);
+ grpc_arg fake_security_name_override = {
+ GRPC_ARG_STRING,
+ const_cast<char*>(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG),
+ {const_cast<char*>("foo.test.google.fr:1234")}};
+ grpc_channel_args* new_client_args = grpc_channel_args_copy_and_add(
+ client_args, &fake_security_name_override, 1);
+ config.init_client(&f, new_client_args);
+ grpc_channel_args_destroy(new_client_args);
+ config.init_server(&f, server_args);
+ return f;
+}
+
+static gpr_timespec n_seconds_from_now(int n) {
+ return grpc_timeout_seconds_to_deadline(n);
+}
+
+static gpr_timespec five_seconds_from_now(void) {
+ return n_seconds_from_now(5);
+}
+
+static void drain_cq(grpc_completion_queue* cq) {
+ grpc_event ev;
+ do {
+ ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr);
+ } while (ev.type != GRPC_QUEUE_SHUTDOWN);
+}
+
+static void shutdown_server(grpc_end2end_test_fixture* f) {
+ if (!f->server) return;
+ grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+ GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+ grpc_timeout_seconds_to_deadline(5),
+ nullptr)
+ .type == GRPC_OP_COMPLETE);
+ grpc_server_destroy(f->server);
+ f->server = nullptr;
+}
+
+static void shutdown_client(grpc_end2end_test_fixture* f) {
+ if (!f->client) return;
+ grpc_channel_destroy(f->client);
+ f->client = nullptr;
+}
+
+static void end_test(grpc_end2end_test_fixture* f) {
+ shutdown_server(f);
+ shutdown_client(f);
+
+ grpc_completion_queue_shutdown(f->cq);
+ drain_cq(f->cq);
+ grpc_completion_queue_destroy(f->cq);
+ grpc_completion_queue_destroy(f->shutdown_cq);
+}
+
+static void test_invoke_simple_request(grpc_end2end_test_config config) {
+ grpc_end2end_test_fixture f =
+ begin_test(config, "test_invoke_simple_request", nullptr, nullptr);
+ grpc_call* c;
+ grpc_call* s;
+ cq_verifier* cqv = cq_verifier_create(f.cq);
+ grpc_op ops[6];
+ grpc_op* op;
+ grpc_metadata_array initial_metadata_recv;
+ grpc_metadata_array trailing_metadata_recv;
+ grpc_metadata_array request_metadata_recv;
+ grpc_call_details call_details;
+ grpc_status_code status;
+ grpc_call_error error;
+ grpc_slice details;
+ int was_cancelled = 2;
+ char* peer;
+
+ gpr_timespec deadline = five_seconds_from_now();
+ c = grpc_channel_create_call(
+ f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
+ nullptr);
+ GPR_ASSERT(c);
+
+ peer = grpc_call_get_peer(c);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "client_peer_before_call=%s", peer);
+ gpr_free(peer);
+
+ grpc_metadata_array_init(&initial_metadata_recv);
+ grpc_metadata_array_init(&trailing_metadata_recv);
+ grpc_metadata_array_init(&request_metadata_recv);
+ grpc_call_details_init(&call_details);
+
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op->flags = 0;
+ op->reserved = nullptr;
+ op++;
+ op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+ op->flags = 0;
+ op->reserved = nullptr;
+ op++;
+ op->op = GRPC_OP_RECV_INITIAL_METADATA;
+ op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
+ op->flags = 0;
+ op->reserved = nullptr;
+ op++;
+ op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+ op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
+ op->data.recv_status_on_client.status = &status;
+ op->data.recv_status_on_client.status_details = &details;
+ op->flags = 0;
+ op->reserved = nullptr;
+ op++;
+ error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
+ nullptr);
+ GPR_ASSERT(error == GRPC_CALL_OK);
+
+ error =
+ grpc_server_request_call(f.server, &s, &call_details,
+ &request_metadata_recv, f.cq, f.cq, tag(101));
+ GPR_ASSERT(error == GRPC_CALL_OK);
+ CQ_EXPECT_COMPLETION(cqv, tag(101), 1);
+ cq_verify(cqv);
+
+ peer = grpc_call_get_peer(s);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "server_peer=%s", peer);
+ gpr_free(peer);
+ peer = grpc_call_get_peer(c);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "client_peer=%s", peer);
+ gpr_free(peer);
+
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op->flags = 0;
+ op->reserved = nullptr;
+ op++;
+ op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+ op->data.send_status_from_server.trailing_metadata_count = 0;
+ op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+ op->data.send_status_from_server.status_details = &status_details;
+ op->flags = 0;
+ op->reserved = nullptr;
+ op++;
+ op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
+ op->data.recv_close_on_server.cancelled = &was_cancelled;
+ op->flags = 0;
+ op->reserved = nullptr;
+ op++;
+ error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102),
+ nullptr);
+ GPR_ASSERT(error == GRPC_CALL_OK);
+
+ CQ_EXPECT_COMPLETION(cqv, tag(102), 1);
+ CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
+ cq_verify(cqv);
+
+ GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
+ GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
+ validate_host_override_string("foo.test.google.fr:1234", call_details.host,
+ config);
+ GPR_ASSERT(was_cancelled == 1);
+
+ grpc_slice_unref(details);
+ grpc_metadata_array_destroy(&initial_metadata_recv);
+ grpc_metadata_array_destroy(&trailing_metadata_recv);
+ grpc_metadata_array_destroy(&request_metadata_recv);
+ grpc_call_details_destroy(&call_details);
+
+ grpc_call_unref(c);
+ grpc_call_unref(s);
+
+ cq_verifier_destroy(cqv);
+
+ end_test(&f);
+ config.tear_down_data(&f);
+}
+
+void call_host_override(grpc_end2end_test_config config) {
+ test_invoke_simple_request(config);
+}
+
+void call_host_override_pre_init(void) {}
diff --git a/test/core/end2end/tests/cancel_after_accept.cc b/test/core/end2end/tests/cancel_after_accept.cc
index e94ea51..788d374 100644
--- a/test/core/end2end/tests/cancel_after_accept.cc
+++ b/test/core/end2end/tests/cancel_after_accept.cc
@@ -146,11 +146,9 @@
gpr_timespec deadline = use_service_config
? gpr_inf_future(GPR_CLOCK_MONOTONIC)
: five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/service/method"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/service/method"),
+ nullptr, deadline, nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
diff --git a/test/core/end2end/tests/cancel_after_client_done.cc b/test/core/end2end/tests/cancel_after_client_done.cc
index 31c3ea6..6e93783 100644
--- a/test/core/end2end/tests/cancel_after_client_done.cc
+++ b/test/core/end2end/tests/cancel_after_client_done.cc
@@ -119,11 +119,9 @@
int was_cancelled = 2;
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
diff --git a/test/core/end2end/tests/cancel_after_invoke.cc b/test/core/end2end/tests/cancel_after_invoke.cc
index 72f7242..78009eb 100644
--- a/test/core/end2end/tests/cancel_after_invoke.cc
+++ b/test/core/end2end/tests/cancel_after_invoke.cc
@@ -113,11 +113,9 @@
grpc_raw_byte_buffer_create(&request_payload_slice, 1);
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
diff --git a/test/core/end2end/tests/cancel_after_round_trip.cc b/test/core/end2end/tests/cancel_after_round_trip.cc
index 4890b30..061b273 100644
--- a/test/core/end2end/tests/cancel_after_round_trip.cc
+++ b/test/core/end2end/tests/cancel_after_round_trip.cc
@@ -148,11 +148,9 @@
gpr_timespec deadline = use_service_config
? gpr_inf_future(GPR_CLOCK_MONOTONIC)
: five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/service/method"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/service/method"),
+ nullptr, deadline, nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
diff --git a/test/core/end2end/tests/cancel_before_invoke.cc b/test/core/end2end/tests/cancel_before_invoke.cc
index c7d3ed5..abb2dbc 100644
--- a/test/core/end2end/tests/cancel_before_invoke.cc
+++ b/test/core/end2end/tests/cancel_before_invoke.cc
@@ -109,11 +109,9 @@
grpc_raw_byte_buffer_create(&request_payload_slice, 1);
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
GPR_ASSERT(GRPC_CALL_OK == grpc_call_cancel(c, nullptr));
diff --git a/test/core/end2end/tests/cancel_in_a_vacuum.cc b/test/core/end2end/tests/cancel_in_a_vacuum.cc
index 6be2d69..4672e64 100644
--- a/test/core/end2end/tests/cancel_in_a_vacuum.cc
+++ b/test/core/end2end/tests/cancel_in_a_vacuum.cc
@@ -97,11 +97,9 @@
cq_verifier* v_client = cq_verifier_create(f.cq);
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
GPR_ASSERT(GRPC_CALL_OK == mode.initiate_cancel(c, nullptr));
diff --git a/test/core/end2end/tests/cancel_with_status.cc b/test/core/end2end/tests/cancel_with_status.cc
index 887da85..2fc9d2f 100644
--- a/test/core/end2end/tests/cancel_with_status.cc
+++ b/test/core/end2end/tests/cancel_with_status.cc
@@ -104,11 +104,9 @@
gpr_log(GPR_DEBUG, "test with %" PRIuPTR " ops", num_ops);
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
diff --git a/test/core/end2end/tests/compressed_payload.cc b/test/core/end2end/tests/compressed_payload.cc
index 85cfe16..178d68c 100644
--- a/test/core/end2end/tests/compressed_payload.cc
+++ b/test/core/end2end/tests/compressed_payload.cc
@@ -137,11 +137,9 @@
cqv = cq_verifier_create(f.cq);
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
@@ -239,8 +237,6 @@
GPR_ASSERT(0 == grpc_slice_str_cmp(details, expected_details));
gpr_free(expected_details);
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
grpc_slice_unref(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
@@ -320,11 +316,9 @@
cqv = cq_verifier_create(f.cq);
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
@@ -529,8 +523,6 @@
GPR_ASSERT(status == GRPC_STATUS_OK);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(was_cancelled == 0);
grpc_slice_unref(details);
diff --git a/test/core/end2end/tests/default_host.cc b/test/core/end2end/tests/default_host.cc
index 3191f76..22c3102 100644
--- a/test/core/end2end/tests/default_host.cc
+++ b/test/core/end2end/tests/default_host.cc
@@ -85,7 +85,9 @@
grpc_completion_queue_destroy(f->shutdown_cq);
}
-static void simple_request_body(grpc_end2end_test_fixture f) {
+static void test_invoke_simple_request(grpc_end2end_test_config config) {
+ grpc_end2end_test_fixture f =
+ begin_test(config, "test_invoke_simple_request", nullptr, nullptr);
grpc_call* c;
grpc_call* s;
cq_verifier* cqv = cq_verifier_create(f.cq);
@@ -191,7 +193,14 @@
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
- GPR_ASSERT(grpc_slice_buf_start_eq(call_details.host, "localhost", 9));
+
+ if (config.overridden_call_host != nullptr) {
+ validate_host_override_string(config.overridden_call_host,
+ call_details.host, config);
+ } else {
+ GPR_ASSERT(grpc_slice_buf_start_eq(call_details.host, "localhost", 9) ||
+ grpc_slice_buf_start_eq(call_details.host, "127.0.0.1", 9));
+ }
GPR_ASSERT(was_cancelled == 1);
grpc_slice_unref(details);
@@ -204,22 +213,12 @@
grpc_call_unref(s);
cq_verifier_destroy(cqv);
-}
-static void test_invoke_simple_request(grpc_end2end_test_config config) {
- grpc_end2end_test_fixture f;
-
- f = begin_test(config, "test_invoke_simple_request", nullptr, nullptr);
- simple_request_body(f);
end_test(&f);
config.tear_down_data(&f);
}
void default_host(grpc_end2end_test_config config) {
- if ((config.feature_mask & FEATURE_MASK_SUPPORTS_HOSTNAME_VERIFICATION) == 0)
- return;
- if ((config.feature_mask & FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION) == 0)
- return;
test_invoke_simple_request(config);
}
diff --git a/test/core/end2end/tests/disappearing_server.cc b/test/core/end2end/tests/disappearing_server.cc
index d5b6f8f..fdd780f 100644
--- a/test/core/end2end/tests/disappearing_server.cc
+++ b/test/core/end2end/tests/disappearing_server.cc
@@ -85,11 +85,9 @@
int was_cancelled = 2;
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f->client, nullptr, GRPC_PROPAGATE_DEFAULTS, f->cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f->client, nullptr, GRPC_PROPAGATE_DEFAULTS,
+ f->cq, grpc_slice_from_static_string("/foo"),
+ nullptr, deadline, nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
@@ -167,8 +165,6 @@
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(was_cancelled == 1);
grpc_slice_unref(details);
diff --git a/test/core/end2end/tests/empty_batch.cc b/test/core/end2end/tests/empty_batch.cc
index 1de4b8f..317bb7a 100644
--- a/test/core/end2end/tests/empty_batch.cc
+++ b/test/core/end2end/tests/empty_batch.cc
@@ -93,11 +93,9 @@
grpc_op* op = nullptr;
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
error = grpc_call_start_batch(c, op, 0, tag(1), nullptr);
diff --git a/test/core/end2end/tests/filter_call_init_fails.cc b/test/core/end2end/tests/filter_call_init_fails.cc
index 6f72a18..ab96879 100644
--- a/test/core/end2end/tests/filter_call_init_fails.cc
+++ b/test/core/end2end/tests/filter_call_init_fails.cc
@@ -117,11 +117,9 @@
grpc_slice details;
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
@@ -213,11 +211,9 @@
grpc_call_error error;
grpc_slice details;
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
@@ -304,11 +300,9 @@
grpc_call_error error;
grpc_slice details;
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
@@ -364,11 +358,9 @@
grpc_slice_unref(details);
details = grpc_empty_slice();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(2),
diff --git a/test/core/end2end/tests/filter_causes_close.cc b/test/core/end2end/tests/filter_causes_close.cc
index bc4cb86..a7f4268 100644
--- a/test/core/end2end/tests/filter_causes_close.cc
+++ b/test/core/end2end/tests/filter_causes_close.cc
@@ -111,11 +111,9 @@
grpc_slice details;
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
diff --git a/test/core/end2end/tests/filter_latency.cc b/test/core/end2end/tests/filter_latency.cc
index 51f54c9..a89db7b 100644
--- a/test/core/end2end/tests/filter_latency.cc
+++ b/test/core/end2end/tests/filter_latency.cc
@@ -125,10 +125,9 @@
const gpr_timespec start_time = gpr_now(GPR_CLOCK_MONOTONIC);
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr", config), deadline, nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
diff --git a/test/core/end2end/tests/filter_status_code.cc b/test/core/end2end/tests/filter_status_code.cc
index 32cd954..ba3cbfa 100644
--- a/test/core/end2end/tests/filter_status_code.cc
+++ b/test/core/end2end/tests/filter_status_code.cc
@@ -126,10 +126,9 @@
gpr_mu_unlock(&g_mu);
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr", config), deadline, nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
gpr_mu_lock(&g_mu);
g_client_call_stack = grpc_call_get_call_stack(c);
diff --git a/test/core/end2end/tests/graceful_server_shutdown.cc b/test/core/end2end/tests/graceful_server_shutdown.cc
index 3ef414f..42f2d1a 100644
--- a/test/core/end2end/tests/graceful_server_shutdown.cc
+++ b/test/core/end2end/tests/graceful_server_shutdown.cc
@@ -99,11 +99,9 @@
int was_cancelled = 2;
gpr_timespec deadline = n_seconds_from_now(10);
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
@@ -183,8 +181,6 @@
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(was_cancelled == 1);
grpc_slice_unref(details);
diff --git a/test/core/end2end/tests/high_initial_seqno.cc b/test/core/end2end/tests/high_initial_seqno.cc
index 8767437..18e6ee9 100644
--- a/test/core/end2end/tests/high_initial_seqno.cc
+++ b/test/core/end2end/tests/high_initial_seqno.cc
@@ -104,11 +104,9 @@
int was_cancelled = 2;
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
@@ -181,8 +179,6 @@
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(was_cancelled == 1);
grpc_slice_unref(details);
diff --git a/test/core/end2end/tests/hpack_size.cc b/test/core/end2end/tests/hpack_size.cc
index b4973684..7c51294 100644
--- a/test/core/end2end/tests/hpack_size.cc
+++ b/test/core/end2end/tests/hpack_size.cc
@@ -257,11 +257,9 @@
grpc_slice_from_static_string(dragons[index % GPR_ARRAY_SIZE(dragons)]);
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
@@ -335,8 +333,6 @@
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(was_cancelled == 1);
grpc_slice_unref(details);
diff --git a/test/core/end2end/tests/idempotent_request.cc b/test/core/end2end/tests/idempotent_request.cc
index 56be2d6..80908d5 100644
--- a/test/core/end2end/tests/idempotent_request.cc
+++ b/test/core/end2end/tests/idempotent_request.cc
@@ -104,11 +104,9 @@
char* peer;
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
peer = grpc_call_get_peer(c);
@@ -195,8 +193,6 @@
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST == call_details.flags);
GPR_ASSERT(was_cancelled == 1);
diff --git a/test/core/end2end/tests/invoke_large_request.cc b/test/core/end2end/tests/invoke_large_request.cc
index 1aab34c..39d90ab 100644
--- a/test/core/end2end/tests/invoke_large_request.cc
+++ b/test/core/end2end/tests/invoke_large_request.cc
@@ -131,11 +131,9 @@
int was_cancelled = 2;
gpr_timespec deadline = n_seconds_from_now(30);
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
@@ -237,8 +235,6 @@
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(was_cancelled == 1);
grpc_slice_unref(details);
diff --git a/test/core/end2end/tests/keepalive_timeout.cc b/test/core/end2end/tests/keepalive_timeout.cc
index c0771b8..1ee5285 100644
--- a/test/core/end2end/tests/keepalive_timeout.cc
+++ b/test/core/end2end/tests/keepalive_timeout.cc
@@ -130,11 +130,9 @@
grpc_set_disable_ping_ack(true);
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
@@ -200,8 +198,6 @@
GPR_ASSERT(status == GRPC_STATUS_INTERNAL);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "keepalive watchdog timeout"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
gpr_free(details_str);
gpr_free(method_str);
diff --git a/test/core/end2end/tests/large_metadata.cc b/test/core/end2end/tests/large_metadata.cc
index da0615b..c7f72a1 100644
--- a/test/core/end2end/tests/large_metadata.cc
+++ b/test/core/end2end/tests/large_metadata.cc
@@ -114,11 +114,9 @@
int was_cancelled = 2;
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
meta.key = grpc_slice_from_static_string("key");
@@ -220,8 +218,6 @@
GPR_ASSERT(status == GRPC_STATUS_OK);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(was_cancelled == 0);
GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, "hello world"));
GPR_ASSERT(contains_metadata_slices(&request_metadata_recv,
diff --git a/test/core/end2end/tests/load_reporting_hook.cc b/test/core/end2end/tests/load_reporting_hook.cc
index 9e79d02..4324e9d 100644
--- a/test/core/end2end/tests/load_reporting_hook.cc
+++ b/test/core/end2end/tests/load_reporting_hook.cc
@@ -138,11 +138,9 @@
int was_cancelled = 2;
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string(method_name),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string(method_name),
+ nullptr, deadline, nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
diff --git a/test/core/end2end/tests/max_concurrent_streams.cc b/test/core/end2end/tests/max_concurrent_streams.cc
index 789b3d4..86a8d22 100644
--- a/test/core/end2end/tests/max_concurrent_streams.cc
+++ b/test/core/end2end/tests/max_concurrent_streams.cc
@@ -100,11 +100,9 @@
int was_cancelled = 2;
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
@@ -177,8 +175,6 @@
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(was_cancelled == 1);
grpc_slice_unref(details);
@@ -248,17 +244,13 @@
/* start two requests - ensuring that the second is not accepted until
the first completes */
deadline = n_seconds_from_now(1000);
- c1 = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/alpha"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c1 = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS,
+ f.cq, grpc_slice_from_static_string("/alpha"),
+ nullptr, deadline, nullptr);
GPR_ASSERT(c1);
- c2 = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/beta"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c2 = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS,
+ f.cq, grpc_slice_from_static_string("/beta"),
+ nullptr, deadline, nullptr);
GPR_ASSERT(c2);
GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(
@@ -494,17 +486,13 @@
/* start two requests - ensuring that the second is not accepted until
the first completes */
- c1 = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/alpha"),
- get_host_override_slice("foo.test.google.fr:1234", config),
- n_seconds_from_now(3), nullptr);
+ c1 = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS,
+ f.cq, grpc_slice_from_static_string("/alpha"),
+ nullptr, n_seconds_from_now(3), nullptr);
GPR_ASSERT(c1);
- c2 = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/beta"),
- get_host_override_slice("foo.test.google.fr:1234", config),
- n_seconds_from_now(1000), nullptr);
+ c2 = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS,
+ f.cq, grpc_slice_from_static_string("/beta"),
+ nullptr, n_seconds_from_now(1000), nullptr);
GPR_ASSERT(c2);
GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(
@@ -694,17 +682,13 @@
/* start two requests - ensuring that the second is not accepted until
the first completes , and the second request will timeout in the
concurrent_list */
- c1 = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/alpha"),
- get_host_override_slice("foo.test.google.fr:1234", config),
- n_seconds_from_now(1000), nullptr);
+ c1 = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS,
+ f.cq, grpc_slice_from_static_string("/alpha"),
+ nullptr, n_seconds_from_now(1000), nullptr);
GPR_ASSERT(c1);
- c2 = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/beta"),
- get_host_override_slice("foo.test.google.fr:1234", config),
- n_seconds_from_now(3), nullptr);
+ c2 = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS,
+ f.cq, grpc_slice_from_static_string("/beta"),
+ nullptr, n_seconds_from_now(3), nullptr);
GPR_ASSERT(c2);
GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(
diff --git a/test/core/end2end/tests/max_connection_age.cc b/test/core/end2end/tests/max_connection_age.cc
index e494dad..fcb0aaf 100644
--- a/test/core/end2end/tests/max_connection_age.cc
+++ b/test/core/end2end/tests/max_connection_age.cc
@@ -109,11 +109,9 @@
grpc_slice details;
int was_cancelled = 2;
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
@@ -208,8 +206,6 @@
the in-progress RPC should fail. */
GPR_ASSERT(status == GRPC_STATUS_INTERNAL);
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(was_cancelled == 1);
grpc_slice_unref(details);
@@ -255,11 +251,9 @@
grpc_slice details;
int was_cancelled = 2;
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
@@ -348,8 +342,6 @@
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(was_cancelled == 1);
grpc_slice_unref(details);
diff --git a/test/core/end2end/tests/max_connection_idle.cc b/test/core/end2end/tests/max_connection_idle.cc
index 2f212b9..faa1383 100644
--- a/test/core/end2end/tests/max_connection_idle.cc
+++ b/test/core/end2end/tests/max_connection_idle.cc
@@ -60,11 +60,9 @@
char* peer;
gpr_timespec deadline = grpc_timeout_seconds_to_deadline(5);
- c = grpc_channel_create_call(
- f->client, nullptr, GRPC_PROPAGATE_DEFAULTS, f->cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f->client, nullptr, GRPC_PROPAGATE_DEFAULTS,
+ f->cq, grpc_slice_from_static_string("/foo"),
+ nullptr, deadline, nullptr);
GPR_ASSERT(c);
peer = grpc_call_get_peer(c);
@@ -151,8 +149,6 @@
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(0 == call_details.flags);
GPR_ASSERT(was_cancelled == 1);
diff --git a/test/core/end2end/tests/max_message_length.cc b/test/core/end2end/tests/max_message_length.cc
index fa5b3b6..6ac941e 100644
--- a/test/core/end2end/tests/max_message_length.cc
+++ b/test/core/end2end/tests/max_message_length.cc
@@ -180,11 +180,10 @@
cqv = cq_verifier_create(f.cq);
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/service/method"),
- get_host_override_slice("foo.test.google.fr:1234", config),
- gpr_inf_future(GPR_CLOCK_REALTIME), nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/service/method"),
+ nullptr, gpr_inf_future(GPR_CLOCK_REALTIME),
+ nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
@@ -258,8 +257,6 @@
cq_verify(cqv);
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(was_cancelled == 1);
done:
@@ -371,11 +368,10 @@
}
cqv = cq_verifier_create(f.cq);
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/service/method"),
- get_host_override_slice("foo.test.google.fr:1234", config),
- gpr_inf_future(GPR_CLOCK_REALTIME), nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/service/method"),
+ nullptr, gpr_inf_future(GPR_CLOCK_REALTIME),
+ nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
@@ -456,9 +452,6 @@
cq_verify(cqv);
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method"));
- GPR_ASSERT(0 ==
- grpc_slice_str_cmp(call_details.host, "foo.test.google.fr:1234"));
-
GPR_ASSERT(status == GRPC_STATUS_RESOURCE_EXHAUSTED);
GPR_ASSERT(
grpc_slice_str_cmp(
diff --git a/test/core/end2end/tests/negative_deadline.cc b/test/core/end2end/tests/negative_deadline.cc
index dce3a02..2b2ff12 100644
--- a/test/core/end2end/tests/negative_deadline.cc
+++ b/test/core/end2end/tests/negative_deadline.cc
@@ -101,11 +101,9 @@
gpr_log(GPR_DEBUG, "test with %" PRIuPTR " ops", num_ops);
gpr_timespec deadline = gpr_inf_past(GPR_CLOCK_REALTIME);
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
diff --git a/test/core/end2end/tests/network_status_change.cc b/test/core/end2end/tests/network_status_change.cc
index 83cb172..98a9558 100644
--- a/test/core/end2end/tests/network_status_change.cc
+++ b/test/core/end2end/tests/network_status_change.cc
@@ -110,11 +110,9 @@
int was_cancelled = 2;
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
@@ -209,8 +207,6 @@
GPR_ASSERT(status == GRPC_STATUS_OK);
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
grpc_slice_unref(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
diff --git a/test/core/end2end/tests/no_logging.cc b/test/core/end2end/tests/no_logging.cc
index b357e3b..c815402 100644
--- a/test/core/end2end/tests/no_logging.cc
+++ b/test/core/end2end/tests/no_logging.cc
@@ -131,11 +131,9 @@
char* peer;
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
peer = grpc_call_get_peer(c);
@@ -219,8 +217,6 @@
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(0 == call_details.flags);
GPR_ASSERT(was_cancelled == 1);
diff --git a/test/core/end2end/tests/payload.cc b/test/core/end2end/tests/payload.cc
index 340c76e..cb6eb47 100644
--- a/test/core/end2end/tests/payload.cc
+++ b/test/core/end2end/tests/payload.cc
@@ -129,11 +129,9 @@
int was_cancelled = 2;
gpr_timespec deadline = n_seconds_from_now(60);
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
@@ -235,8 +233,6 @@
GPR_ASSERT(status == GRPC_STATUS_OK);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(was_cancelled == 0);
GPR_ASSERT(byte_buffer_eq_slice(request_payload_recv, request_payload_slice));
GPR_ASSERT(
diff --git a/test/core/end2end/tests/ping_pong_streaming.cc b/test/core/end2end/tests/ping_pong_streaming.cc
index 9ca8804..30ee0bf 100644
--- a/test/core/end2end/tests/ping_pong_streaming.cc
+++ b/test/core/end2end/tests/ping_pong_streaming.cc
@@ -112,11 +112,9 @@
grpc_slice_from_copied_string("hello you");
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
diff --git a/test/core/end2end/tests/proxy_auth.cc b/test/core/end2end/tests/proxy_auth.cc
index 5a2e0ef..3b12869 100644
--- a/test/core/end2end/tests/proxy_auth.cc
+++ b/test/core/end2end/tests/proxy_auth.cc
@@ -108,11 +108,9 @@
char* peer;
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
peer = grpc_call_get_peer(c);
@@ -199,8 +197,6 @@
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(0 == call_details.flags);
GPR_ASSERT(was_cancelled == 1);
diff --git a/test/core/end2end/tests/registered_call.cc b/test/core/end2end/tests/registered_call.cc
index d4ca146..3e05fd1 100644
--- a/test/core/end2end/tests/registered_call.cc
+++ b/test/core/end2end/tests/registered_call.cc
@@ -177,8 +177,6 @@
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(was_cancelled == 1);
grpc_slice_unref(details);
@@ -196,9 +194,7 @@
static void test_invoke_simple_request(grpc_end2end_test_config config) {
grpc_end2end_test_fixture f =
begin_test(config, "test_invoke_simple_request", nullptr, nullptr);
- void* rc = grpc_channel_register_call(
- f.client, "/foo",
- get_host_override_string("foo.test.google.fr:1234", config), nullptr);
+ void* rc = grpc_channel_register_call(f.client, "/foo", nullptr, nullptr);
simple_request_body(config, f, rc);
end_test(&f);
@@ -209,9 +205,7 @@
int i;
grpc_end2end_test_fixture f =
begin_test(config, "test_invoke_10_simple_requests", nullptr, nullptr);
- void* rc = grpc_channel_register_call(
- f.client, "/foo",
- get_host_override_string("foo.test.google.fr:1234", config), nullptr);
+ void* rc = grpc_channel_register_call(f.client, "/foo", nullptr, nullptr);
for (i = 0; i < 10; i++) {
simple_request_body(config, f, rc);
diff --git a/test/core/end2end/tests/request_with_flags.cc b/test/core/end2end/tests/request_with_flags.cc
index c524824..f3baf37 100644
--- a/test/core/end2end/tests/request_with_flags.cc
+++ b/test/core/end2end/tests/request_with_flags.cc
@@ -108,11 +108,9 @@
grpc_call_error expectation;
gpr_timespec deadline = one_second_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
diff --git a/test/core/end2end/tests/request_with_payload.cc b/test/core/end2end/tests/request_with_payload.cc
index 44398df..37d9481 100644
--- a/test/core/end2end/tests/request_with_payload.cc
+++ b/test/core/end2end/tests/request_with_payload.cc
@@ -107,11 +107,9 @@
int was_cancelled = 2;
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
@@ -202,8 +200,6 @@
GPR_ASSERT(status == GRPC_STATUS_OK);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(was_cancelled == 0);
GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, "hello world"));
diff --git a/test/core/end2end/tests/resource_quota_server.cc b/test/core/end2end/tests/resource_quota_server.cc
index 33d6b4e..df83caa 100644
--- a/test/core/end2end/tests/resource_quota_server.cc
+++ b/test/core/end2end/tests/resource_quota_server.cc
@@ -188,11 +188,10 @@
}
for (int i = 0; i < NUM_CALLS; i++) {
- client_calls[i] = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr", config),
- n_seconds_from_now(60), nullptr);
+ client_calls[i] =
+ grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS,
+ f.cq, grpc_slice_from_static_string("/foo"),
+ nullptr, n_seconds_from_now(60), nullptr);
memset(ops, 0, sizeof(ops));
op = ops;
diff --git a/test/core/end2end/tests/retry.cc b/test/core/end2end/tests/retry.cc
index 38ecc6f..243dedc 100644
--- a/test/core/end2end/tests/retry.cc
+++ b/test/core/end2end/tests/retry.cc
@@ -145,11 +145,9 @@
cq_verifier* cqv = cq_verifier_create(f.cq);
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/service/method"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/service/method"),
+ nullptr, deadline, nullptr);
GPR_ASSERT(c);
peer = grpc_call_get_peer(c);
@@ -293,8 +291,6 @@
GPR_ASSERT(status == GRPC_STATUS_OK);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(0 == call_details.flags);
GPR_ASSERT(was_cancelled == 0);
diff --git a/test/core/end2end/tests/retry_cancellation.cc b/test/core/end2end/tests/retry_cancellation.cc
index 0504092..e764fe7 100644
--- a/test/core/end2end/tests/retry_cancellation.cc
+++ b/test/core/end2end/tests/retry_cancellation.cc
@@ -146,11 +146,9 @@
cq_verifier* cqv = cq_verifier_create(f.cq);
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/service/method"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/service/method"),
+ nullptr, deadline, nullptr);
GPR_ASSERT(c);
peer = grpc_call_get_peer(c);
diff --git a/test/core/end2end/tests/retry_disabled.cc b/test/core/end2end/tests/retry_disabled.cc
index cb30502..ed35354 100644
--- a/test/core/end2end/tests/retry_disabled.cc
+++ b/test/core/end2end/tests/retry_disabled.cc
@@ -149,11 +149,9 @@
cq_verifier* cqv = cq_verifier_create(f.cq);
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/service/method"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/service/method"),
+ nullptr, deadline, nullptr);
GPR_ASSERT(c);
peer = grpc_call_get_peer(c);
@@ -230,8 +228,6 @@
GPR_ASSERT(status == GRPC_STATUS_ABORTED);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(0 == call_details.flags);
GPR_ASSERT(was_cancelled == 1);
diff --git a/test/core/end2end/tests/retry_exceeds_buffer_size_in_initial_batch.cc b/test/core/end2end/tests/retry_exceeds_buffer_size_in_initial_batch.cc
index 3908f29..a033a0a 100644
--- a/test/core/end2end/tests/retry_exceeds_buffer_size_in_initial_batch.cc
+++ b/test/core/end2end/tests/retry_exceeds_buffer_size_in_initial_batch.cc
@@ -152,11 +152,9 @@
cq_verifier* cqv = cq_verifier_create(f.cq);
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/service/method"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/service/method"),
+ nullptr, deadline, nullptr);
GPR_ASSERT(c);
peer = grpc_call_get_peer(c);
@@ -233,8 +231,6 @@
GPR_ASSERT(status == GRPC_STATUS_ABORTED);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(0 == call_details.flags);
GPR_ASSERT(was_cancelled == 1);
diff --git a/test/core/end2end/tests/retry_exceeds_buffer_size_in_subsequent_batch.cc b/test/core/end2end/tests/retry_exceeds_buffer_size_in_subsequent_batch.cc
index 409fac4..c1070e6 100644
--- a/test/core/end2end/tests/retry_exceeds_buffer_size_in_subsequent_batch.cc
+++ b/test/core/end2end/tests/retry_exceeds_buffer_size_in_subsequent_batch.cc
@@ -157,11 +157,9 @@
cq_verifier* cqv = cq_verifier_create(f.cq);
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/service/method"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/service/method"),
+ nullptr, deadline, nullptr);
GPR_ASSERT(c);
peer = grpc_call_get_peer(c);
@@ -245,8 +243,6 @@
GPR_ASSERT(status == GRPC_STATUS_ABORTED);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(0 == call_details.flags);
GPR_ASSERT(was_cancelled == 1);
diff --git a/test/core/end2end/tests/retry_non_retriable_status.cc b/test/core/end2end/tests/retry_non_retriable_status.cc
index 6d59db0..b8d0947 100644
--- a/test/core/end2end/tests/retry_non_retriable_status.cc
+++ b/test/core/end2end/tests/retry_non_retriable_status.cc
@@ -144,11 +144,9 @@
cq_verifier* cqv = cq_verifier_create(f.cq);
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/service/method"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/service/method"),
+ nullptr, deadline, nullptr);
GPR_ASSERT(c);
peer = grpc_call_get_peer(c);
@@ -225,8 +223,6 @@
GPR_ASSERT(status == GRPC_STATUS_INVALID_ARGUMENT);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(0 == call_details.flags);
GPR_ASSERT(was_cancelled == 1);
diff --git a/test/core/end2end/tests/retry_non_retriable_status_before_recv_trailing_metadata_started.cc b/test/core/end2end/tests/retry_non_retriable_status_before_recv_trailing_metadata_started.cc
new file mode 100644
index 0000000..eb016a3
--- /dev/null
+++ b/test/core/end2end/tests/retry_non_retriable_status_before_recv_trailing_metadata_started.cc
@@ -0,0 +1,266 @@
+/*
+ *
+ * Copyright 2018 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.
+ *
+ */
+
+#include "test/core/end2end/end2end_tests.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include <grpc/byte_buffer.h>
+#include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+#include <grpc/support/time.h>
+
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gpr/useful.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
+#include "src/core/lib/transport/static_metadata.h"
+
+#include "test/core/end2end/cq_verifier.h"
+#include "test/core/end2end/tests/cancel_test_helpers.h"
+
+static void* tag(intptr_t t) { return (void*)t; }
+
+static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
+ const char* test_name,
+ grpc_channel_args* client_args,
+ grpc_channel_args* server_args) {
+ grpc_end2end_test_fixture f;
+ gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name);
+ f = config.create_fixture(client_args, server_args);
+ config.init_server(&f, server_args);
+ config.init_client(&f, client_args);
+ return f;
+}
+
+static gpr_timespec n_seconds_from_now(int n) {
+ return grpc_timeout_seconds_to_deadline(n);
+}
+
+static gpr_timespec five_seconds_from_now(void) {
+ return n_seconds_from_now(5);
+}
+
+static void drain_cq(grpc_completion_queue* cq) {
+ grpc_event ev;
+ do {
+ ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr);
+ } while (ev.type != GRPC_QUEUE_SHUTDOWN);
+}
+
+static void shutdown_server(grpc_end2end_test_fixture* f) {
+ if (!f->server) return;
+ grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+ GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+ grpc_timeout_seconds_to_deadline(5),
+ nullptr)
+ .type == GRPC_OP_COMPLETE);
+ grpc_server_destroy(f->server);
+ f->server = nullptr;
+}
+
+static void shutdown_client(grpc_end2end_test_fixture* f) {
+ if (!f->client) return;
+ grpc_channel_destroy(f->client);
+ f->client = nullptr;
+}
+
+static void end_test(grpc_end2end_test_fixture* f) {
+ shutdown_server(f);
+ shutdown_client(f);
+
+ grpc_completion_queue_shutdown(f->cq);
+ drain_cq(f->cq);
+ grpc_completion_queue_destroy(f->cq);
+ grpc_completion_queue_destroy(f->shutdown_cq);
+}
+
+// Tests that we don't retry for non-retryable status codes, even if
+// status is received before the recv_trailing_metadata op is started.
+// - 1 retry allowed for ABORTED status
+// - first attempt gets INVALID_ARGUMENT, so no retry is done
+static void
+test_retry_non_retriable_status_before_recv_trailing_metadata_started(
+ grpc_end2end_test_config config) {
+ grpc_call* c;
+ grpc_call* s;
+ grpc_op ops[6];
+ grpc_op* op;
+ grpc_metadata_array initial_metadata_recv;
+ grpc_metadata_array trailing_metadata_recv;
+ grpc_metadata_array request_metadata_recv;
+ grpc_call_details call_details;
+ grpc_slice request_payload_slice = grpc_slice_from_static_string("foo");
+ grpc_slice response_payload_slice = grpc_slice_from_static_string("bar");
+ grpc_byte_buffer* request_payload =
+ grpc_raw_byte_buffer_create(&request_payload_slice, 1);
+ grpc_byte_buffer* response_payload =
+ grpc_raw_byte_buffer_create(&response_payload_slice, 1);
+ grpc_byte_buffer* request_payload_recv = nullptr;
+ grpc_byte_buffer* response_payload_recv = nullptr;
+ grpc_status_code status;
+ grpc_call_error error;
+ grpc_slice details;
+ int was_cancelled = 2;
+ char* peer;
+
+ grpc_arg arg;
+ arg.type = GRPC_ARG_STRING;
+ arg.key = const_cast<char*>(GRPC_ARG_SERVICE_CONFIG);
+ arg.value.string = const_cast<char*>(
+ "{\n"
+ " \"methodConfig\": [ {\n"
+ " \"name\": [\n"
+ " { \"service\": \"service\", \"method\": \"method\" }\n"
+ " ],\n"
+ " \"retryPolicy\": {\n"
+ " \"maxAttempts\": 2,\n"
+ " \"initialBackoff\": \"1s\",\n"
+ " \"maxBackoff\": \"120s\",\n"
+ " \"backoffMultiplier\": 1.6,\n"
+ " \"retryableStatusCodes\": [ \"ABORTED\" ]\n"
+ " }\n"
+ " } ]\n"
+ "}");
+ grpc_channel_args client_args = {1, &arg};
+ grpc_end2end_test_fixture f =
+ begin_test(config, "retry_non_retriable_status", &client_args, nullptr);
+
+ cq_verifier* cqv = cq_verifier_create(f.cq);
+
+ gpr_timespec deadline = five_seconds_from_now();
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/service/method"),
+ nullptr, deadline, nullptr);
+ GPR_ASSERT(c);
+
+ peer = grpc_call_get_peer(c);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "client_peer_before_call=%s", peer);
+ gpr_free(peer);
+
+ grpc_metadata_array_init(&initial_metadata_recv);
+ grpc_metadata_array_init(&trailing_metadata_recv);
+ grpc_metadata_array_init(&request_metadata_recv);
+ grpc_call_details_init(&call_details);
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op++;
+ op->op = GRPC_OP_SEND_MESSAGE;
+ op->data.send_message.send_message = request_payload;
+ op++;
+ op->op = GRPC_OP_RECV_MESSAGE;
+ op->data.recv_message.recv_message = &response_payload_recv;
+ op++;
+ op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+ op++;
+ op->op = GRPC_OP_RECV_INITIAL_METADATA;
+ op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
+ op++;
+ error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+
+ error =
+ grpc_server_request_call(f.server, &s, &call_details,
+ &request_metadata_recv, f.cq, f.cq, tag(101));
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(101), true);
+ cq_verify(cqv);
+
+ peer = grpc_call_get_peer(s);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "server_peer=%s", peer);
+ gpr_free(peer);
+ peer = grpc_call_get_peer(c);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "client_peer=%s", peer);
+ gpr_free(peer);
+
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op++;
+ op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+ op->data.send_status_from_server.trailing_metadata_count = 0;
+ op->data.send_status_from_server.status = GRPC_STATUS_INVALID_ARGUMENT;
+ op->data.send_status_from_server.status_details = &status_details;
+ op++;
+ op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
+ op->data.recv_close_on_server.cancelled = &was_cancelled;
+ op++;
+ error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+
+ CQ_EXPECT_COMPLETION(cqv, tag(102), true);
+ CQ_EXPECT_COMPLETION(cqv, tag(1), true);
+ cq_verify(cqv);
+
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+ op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
+ op->data.recv_status_on_client.status = &status;
+ op->data.recv_status_on_client.status_details = &details;
+ op++;
+ error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(2), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+
+ CQ_EXPECT_COMPLETION(cqv, tag(2), true);
+ cq_verify(cqv);
+
+ GPR_ASSERT(status == GRPC_STATUS_INVALID_ARGUMENT);
+ GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method"));
+ GPR_ASSERT(0 == call_details.flags);
+ GPR_ASSERT(was_cancelled == 1);
+
+ grpc_slice_unref(details);
+ grpc_metadata_array_destroy(&initial_metadata_recv);
+ grpc_metadata_array_destroy(&trailing_metadata_recv);
+ grpc_metadata_array_destroy(&request_metadata_recv);
+ grpc_call_details_destroy(&call_details);
+ grpc_byte_buffer_destroy(request_payload);
+ grpc_byte_buffer_destroy(response_payload);
+ grpc_byte_buffer_destroy(request_payload_recv);
+ grpc_byte_buffer_destroy(response_payload_recv);
+
+ grpc_call_unref(c);
+ grpc_call_unref(s);
+
+ cq_verifier_destroy(cqv);
+
+ end_test(&f);
+ config.tear_down_data(&f);
+}
+
+void retry_non_retriable_status_before_recv_trailing_metadata_started(
+ grpc_end2end_test_config config) {
+ GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL);
+ test_retry_non_retriable_status_before_recv_trailing_metadata_started(config);
+}
+
+void retry_non_retriable_status_before_recv_trailing_metadata_started_pre_init() {
+}
diff --git a/test/core/end2end/tests/retry_recv_initial_metadata.cc b/test/core/end2end/tests/retry_recv_initial_metadata.cc
index 14215e4..839b870 100644
--- a/test/core/end2end/tests/retry_recv_initial_metadata.cc
+++ b/test/core/end2end/tests/retry_recv_initial_metadata.cc
@@ -145,11 +145,9 @@
cq_verifier* cqv = cq_verifier_create(f.cq);
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/service/method"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/service/method"),
+ nullptr, deadline, nullptr);
GPR_ASSERT(c);
peer = grpc_call_get_peer(c);
@@ -236,8 +234,6 @@
GPR_ASSERT(status == GRPC_STATUS_ABORTED);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(0 == call_details.flags);
GPR_ASSERT(was_cancelled == 1);
diff --git a/test/core/end2end/tests/retry_recv_message.cc b/test/core/end2end/tests/retry_recv_message.cc
index 86171fd..5fdaad0 100644
--- a/test/core/end2end/tests/retry_recv_message.cc
+++ b/test/core/end2end/tests/retry_recv_message.cc
@@ -145,11 +145,9 @@
cq_verifier* cqv = cq_verifier_create(f.cq);
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/service/method"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/service/method"),
+ nullptr, deadline, nullptr);
GPR_ASSERT(c);
peer = grpc_call_get_peer(c);
@@ -229,8 +227,6 @@
GPR_ASSERT(status == GRPC_STATUS_ABORTED);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(0 == call_details.flags);
GPR_ASSERT(was_cancelled == 1);
diff --git a/test/core/end2end/tests/retry_server_pushback_delay.cc b/test/core/end2end/tests/retry_server_pushback_delay.cc
index 1da9860..f6a9796 100644
--- a/test/core/end2end/tests/retry_server_pushback_delay.cc
+++ b/test/core/end2end/tests/retry_server_pushback_delay.cc
@@ -150,11 +150,9 @@
cq_verifier* cqv = cq_verifier_create(f.cq);
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/service/method"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/service/method"),
+ nullptr, deadline, nullptr);
GPR_ASSERT(c);
peer = grpc_call_get_peer(c);
@@ -286,8 +284,6 @@
GPR_ASSERT(status == GRPC_STATUS_OK);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(0 == call_details.flags);
GPR_ASSERT(was_cancelled == 0);
diff --git a/test/core/end2end/tests/retry_server_pushback_disabled.cc b/test/core/end2end/tests/retry_server_pushback_disabled.cc
index 13d4f01..1c56476 100644
--- a/test/core/end2end/tests/retry_server_pushback_disabled.cc
+++ b/test/core/end2end/tests/retry_server_pushback_disabled.cc
@@ -151,11 +151,9 @@
cq_verifier* cqv = cq_verifier_create(f.cq);
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/service/method"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/service/method"),
+ nullptr, deadline, nullptr);
GPR_ASSERT(c);
peer = grpc_call_get_peer(c);
@@ -274,8 +272,6 @@
GPR_ASSERT(status == GRPC_STATUS_ABORTED);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(0 == call_details.flags);
GPR_ASSERT(was_cancelled == 1);
diff --git a/test/core/end2end/tests/retry_streaming.cc b/test/core/end2end/tests/retry_streaming.cc
index e96e57e..d06d124 100644
--- a/test/core/end2end/tests/retry_streaming.cc
+++ b/test/core/end2end/tests/retry_streaming.cc
@@ -158,11 +158,9 @@
cq_verifier* cqv = cq_verifier_create(f.cq);
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/service/method"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/service/method"),
+ nullptr, deadline, nullptr);
GPR_ASSERT(c);
peer = grpc_call_get_peer(c);
@@ -383,8 +381,6 @@
GPR_ASSERT(status == GRPC_STATUS_ABORTED);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(0 == call_details.flags);
GPR_ASSERT(was_cancelled == 1);
diff --git a/test/core/end2end/tests/retry_streaming_after_commit.cc b/test/core/end2end/tests/retry_streaming_after_commit.cc
index 43eee86..05025d0 100644
--- a/test/core/end2end/tests/retry_streaming_after_commit.cc
+++ b/test/core/end2end/tests/retry_streaming_after_commit.cc
@@ -151,11 +151,9 @@
cq_verifier* cqv = cq_verifier_create(f.cq);
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/service/method"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/service/method"),
+ nullptr, deadline, nullptr);
GPR_ASSERT(c);
peer = grpc_call_get_peer(c);
@@ -312,8 +310,6 @@
GPR_ASSERT(status == GRPC_STATUS_ABORTED);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(0 == call_details.flags);
GPR_ASSERT(was_cancelled == 1);
diff --git a/test/core/end2end/tests/retry_streaming_succeeds_before_replay_finished.cc b/test/core/end2end/tests/retry_streaming_succeeds_before_replay_finished.cc
index 5c92f64..14460d2 100644
--- a/test/core/end2end/tests/retry_streaming_succeeds_before_replay_finished.cc
+++ b/test/core/end2end/tests/retry_streaming_succeeds_before_replay_finished.cc
@@ -152,11 +152,9 @@
cq_verifier* cqv = cq_verifier_create(f.cq);
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/service/method"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/service/method"),
+ nullptr, deadline, nullptr);
GPR_ASSERT(c);
peer = grpc_call_get_peer(c);
@@ -364,8 +362,6 @@
GPR_ASSERT(status == GRPC_STATUS_ABORTED);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(0 == call_details.flags);
GPR_ASSERT(was_cancelled == 1);
diff --git a/test/core/end2end/tests/retry_throttled.cc b/test/core/end2end/tests/retry_throttled.cc
index 8cd0848..f5b28de 100644
--- a/test/core/end2end/tests/retry_throttled.cc
+++ b/test/core/end2end/tests/retry_throttled.cc
@@ -151,11 +151,9 @@
cq_verifier* cqv = cq_verifier_create(f.cq);
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/service/method"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/service/method"),
+ nullptr, deadline, nullptr);
GPR_ASSERT(c);
peer = grpc_call_get_peer(c);
@@ -232,8 +230,6 @@
GPR_ASSERT(status == GRPC_STATUS_ABORTED);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(0 == call_details.flags);
GPR_ASSERT(was_cancelled == 1);
diff --git a/test/core/end2end/tests/retry_too_many_attempts.cc b/test/core/end2end/tests/retry_too_many_attempts.cc
index 5225c9b..2af3267 100644
--- a/test/core/end2end/tests/retry_too_many_attempts.cc
+++ b/test/core/end2end/tests/retry_too_many_attempts.cc
@@ -145,11 +145,9 @@
cq_verifier* cqv = cq_verifier_create(f.cq);
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/service/method"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/service/method"),
+ nullptr, deadline, nullptr);
GPR_ASSERT(c);
peer = grpc_call_get_peer(c);
@@ -267,8 +265,6 @@
GPR_ASSERT(status == GRPC_STATUS_ABORTED);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(0 == call_details.flags);
GPR_ASSERT(was_cancelled == 1);
diff --git a/test/core/end2end/tests/server_finishes_request.cc b/test/core/end2end/tests/server_finishes_request.cc
index 6fc06cf..c81b309 100644
--- a/test/core/end2end/tests/server_finishes_request.cc
+++ b/test/core/end2end/tests/server_finishes_request.cc
@@ -102,11 +102,9 @@
int was_cancelled = 2;
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
@@ -175,8 +173,6 @@
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(was_cancelled == 1);
grpc_slice_unref(details);
diff --git a/test/core/end2end/tests/shutdown_finishes_calls.cc b/test/core/end2end/tests/shutdown_finishes_calls.cc
index 28728ef..5dd5bb2 100644
--- a/test/core/end2end/tests/shutdown_finishes_calls.cc
+++ b/test/core/end2end/tests/shutdown_finishes_calls.cc
@@ -92,11 +92,9 @@
int was_cancelled = 2;
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
@@ -172,8 +170,6 @@
GPR_ASSERT(status == GRPC_STATUS_INTERNAL ||
status == GRPC_STATUS_UNAVAILABLE);
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(was_cancelled == 1);
grpc_slice_unref(details);
diff --git a/test/core/end2end/tests/simple_cacheable_request.cc b/test/core/end2end/tests/simple_cacheable_request.cc
index 4ae8398a..be6d16e 100644
--- a/test/core/end2end/tests/simple_cacheable_request.cc
+++ b/test/core/end2end/tests/simple_cacheable_request.cc
@@ -132,11 +132,9 @@
int was_cancelled = 2;
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
@@ -240,8 +238,6 @@
GPR_ASSERT(status == GRPC_STATUS_OK);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
if (config.feature_mask & FEATURE_MASK_SUPPORTS_REQUEST_PROXYING) {
// Our simple proxy does not support cacheable requests
} else {
diff --git a/test/core/end2end/tests/simple_delayed_request.cc b/test/core/end2end/tests/simple_delayed_request.cc
index f8a1ddf..8d11699 100644
--- a/test/core/end2end/tests/simple_delayed_request.cc
+++ b/test/core/end2end/tests/simple_delayed_request.cc
@@ -94,11 +94,9 @@
config.init_server(f, server_args);
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f->client, nullptr, GRPC_PROPAGATE_DEFAULTS, f->cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f->client, nullptr, GRPC_PROPAGATE_DEFAULTS,
+ f->cq, grpc_slice_from_static_string("/foo"),
+ nullptr, deadline, nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
@@ -171,8 +169,6 @@
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(was_cancelled == 1);
grpc_slice_unref(details);
diff --git a/test/core/end2end/tests/simple_metadata.cc b/test/core/end2end/tests/simple_metadata.cc
index 1f39f89..3e476c2 100644
--- a/test/core/end2end/tests/simple_metadata.cc
+++ b/test/core/end2end/tests/simple_metadata.cc
@@ -130,11 +130,9 @@
int was_cancelled = 2;
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
@@ -238,8 +236,6 @@
GPR_ASSERT(status == GRPC_STATUS_OK);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(was_cancelled == 0);
GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, "hello world"));
GPR_ASSERT(byte_buffer_eq_string(response_payload_recv, "hello you"));
diff --git a/test/core/end2end/tests/simple_request.cc b/test/core/end2end/tests/simple_request.cc
index 926e2c7..2d6ccad 100644
--- a/test/core/end2end/tests/simple_request.cc
+++ b/test/core/end2end/tests/simple_request.cc
@@ -111,11 +111,9 @@
grpc_stats_collect(before);
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
peer = grpc_call_get_peer(c);
@@ -212,8 +210,6 @@
GPR_ASSERT(nullptr != strstr(error_string, "grpc_message"));
GPR_ASSERT(nullptr != strstr(error_string, "grpc_status"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(0 == call_details.flags);
GPR_ASSERT(was_cancelled == 1);
diff --git a/test/core/end2end/tests/stream_compression_compressed_payload.cc b/test/core/end2end/tests/stream_compression_compressed_payload.cc
index e90d54f..839f091 100644
--- a/test/core/end2end/tests/stream_compression_compressed_payload.cc
+++ b/test/core/end2end/tests/stream_compression_compressed_payload.cc
@@ -137,11 +137,9 @@
cqv = cq_verifier_create(f.cq);
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
@@ -239,8 +237,6 @@
GPR_ASSERT(0 == grpc_slice_str_cmp(details, expected_details));
gpr_free(expected_details);
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
grpc_slice_unref(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
@@ -327,11 +323,9 @@
cqv = cq_verifier_create(f.cq);
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
@@ -529,8 +523,6 @@
GPR_ASSERT(status == GRPC_STATUS_OK);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(was_cancelled == 0);
grpc_slice_unref(details);
diff --git a/test/core/end2end/tests/stream_compression_payload.cc b/test/core/end2end/tests/stream_compression_payload.cc
index 9eace97..4c08150 100644
--- a/test/core/end2end/tests/stream_compression_payload.cc
+++ b/test/core/end2end/tests/stream_compression_payload.cc
@@ -132,11 +132,9 @@
int was_cancelled = 2;
gpr_timespec deadline = n_seconds_from_now(60);
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
@@ -238,8 +236,6 @@
GPR_ASSERT(status == GRPC_STATUS_OK);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(was_cancelled == 0);
GPR_ASSERT(byte_buffer_eq_slice(request_payload_recv, request_payload_slice));
GPR_ASSERT(
diff --git a/test/core/end2end/tests/stream_compression_ping_pong_streaming.cc b/test/core/end2end/tests/stream_compression_ping_pong_streaming.cc
index 5b03329..f7af59f 100644
--- a/test/core/end2end/tests/stream_compression_ping_pong_streaming.cc
+++ b/test/core/end2end/tests/stream_compression_ping_pong_streaming.cc
@@ -120,11 +120,9 @@
grpc_slice_from_copied_string("hello you");
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
diff --git a/test/core/end2end/tests/streaming_error_response.cc b/test/core/end2end/tests/streaming_error_response.cc
index 7c7d778..4c357e0 100644
--- a/test/core/end2end/tests/streaming_error_response.cc
+++ b/test/core/end2end/tests/streaming_error_response.cc
@@ -116,11 +116,9 @@
int was_cancelled = 2;
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
@@ -244,8 +242,6 @@
GPR_ASSERT(status == GRPC_STATUS_FAILED_PRECONDITION);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(was_cancelled == 1);
grpc_slice_unref(details);
diff --git a/test/core/end2end/tests/trailing_metadata.cc b/test/core/end2end/tests/trailing_metadata.cc
index 2406985..5cf6f2b 100644
--- a/test/core/end2end/tests/trailing_metadata.cc
+++ b/test/core/end2end/tests/trailing_metadata.cc
@@ -138,11 +138,9 @@
int was_cancelled = 2;
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
@@ -247,8 +245,6 @@
GPR_ASSERT(status == GRPC_STATUS_OK);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, "hello world"));
GPR_ASSERT(byte_buffer_eq_string(response_payload_recv, "hello you"));
GPR_ASSERT(contains_metadata(&request_metadata_recv, "key1", "val1"));
diff --git a/test/core/end2end/tests/workaround_cronet_compression.cc b/test/core/end2end/tests/workaround_cronet_compression.cc
index 4d4c369..f44ddca 100644
--- a/test/core/end2end/tests/workaround_cronet_compression.cc
+++ b/test/core/end2end/tests/workaround_cronet_compression.cc
@@ -155,11 +155,9 @@
cqv = cq_verifier_create(f.cq);
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
@@ -338,8 +336,6 @@
GPR_ASSERT(status == GRPC_STATUS_OK);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(was_cancelled == 0);
grpc_slice_unref(details);
diff --git a/test/core/end2end/tests/write_buffering.cc b/test/core/end2end/tests/write_buffering.cc
index 5d76d23..2f7ee9c 100644
--- a/test/core/end2end/tests/write_buffering.cc
+++ b/test/core/end2end/tests/write_buffering.cc
@@ -111,11 +111,9 @@
int was_cancelled = 2;
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
@@ -255,8 +253,6 @@
GPR_ASSERT(status == GRPC_STATUS_OK);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(was_cancelled == 0);
GPR_ASSERT(byte_buffer_eq_string(request_payload_recv1, "hello world"));
GPR_ASSERT(byte_buffer_eq_string(request_payload_recv2, "abc123"));
diff --git a/test/core/end2end/tests/write_buffering_at_end.cc b/test/core/end2end/tests/write_buffering_at_end.cc
index bd046ef..886d491 100644
--- a/test/core/end2end/tests/write_buffering_at_end.cc
+++ b/test/core/end2end/tests/write_buffering_at_end.cc
@@ -108,11 +108,9 @@
int was_cancelled = 2;
gpr_timespec deadline = five_seconds_from_now();
- c = grpc_channel_create_call(
- f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
- grpc_slice_from_static_string("/foo"),
- get_host_override_slice("foo.test.google.fr:1234", config), deadline,
- nullptr);
+ c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"), nullptr,
+ deadline, nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
@@ -246,8 +244,6 @@
GPR_ASSERT(status == GRPC_STATUS_OK);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
- validate_host_override_string("foo.test.google.fr:1234", call_details.host,
- config);
GPR_ASSERT(was_cancelled == 0);
GPR_ASSERT(byte_buffer_eq_string(request_payload_recv1, "hello world"));
GPR_ASSERT(request_payload_recv2 == nullptr);
diff --git a/test/core/gprpp/inlined_vector_test.cc b/test/core/gprpp/inlined_vector_test.cc
index 2a35742..ae34947 100644
--- a/test/core/gprpp/inlined_vector_test.cc
+++ b/test/core/gprpp/inlined_vector_test.cc
@@ -33,6 +33,7 @@
EXPECT_EQ(static_cast<size_t>(kNumElements), v.size());
for (int i = 0; i < kNumElements; ++i) {
EXPECT_EQ(i, v[i]);
+ EXPECT_EQ(i, &v[i] - &v[0]); // Ensure contiguous allocation.
}
}
diff --git a/test/core/gprpp/ref_counted_ptr_test.cc b/test/core/gprpp/ref_counted_ptr_test.cc
index 2e398a7..c810345 100644
--- a/test/core/gprpp/ref_counted_ptr_test.cc
+++ b/test/core/gprpp/ref_counted_ptr_test.cc
@@ -88,7 +88,7 @@
TEST(RefCountedPtr, CopyAssignmentToSelf) {
RefCountedPtr<Foo> foo(New<Foo>());
- foo = foo;
+ foo = *&foo; // The "*&" avoids warnings from LLVM -Wself-assign.
}
TEST(RefCountedPtr, EnclosedScope) {
diff --git a/test/core/handshake/readahead_handshaker_server_ssl.cc b/test/core/handshake/readahead_handshaker_server_ssl.cc
index 9788320..97e9c20 100644
--- a/test/core/handshake/readahead_handshaker_server_ssl.cc
+++ b/test/core/handshake/readahead_handshaker_server_ssl.cc
@@ -64,7 +64,7 @@
const grpc_handshaker_vtable readahead_handshaker_vtable = {
readahead_handshaker_destroy, readahead_handshaker_shutdown,
- readahead_handshaker_do_handshake};
+ readahead_handshaker_do_handshake, "read_ahead"};
static grpc_handshaker* readahead_handshaker_create() {
grpc_handshaker* h =
diff --git a/test/core/iomgr/udp_server_test.cc b/test/core/iomgr/udp_server_test.cc
index 3058e87..d167c01 100644
--- a/test/core/iomgr/udp_server_test.cc
+++ b/test/core/iomgr/udp_server_test.cc
@@ -40,6 +40,7 @@
#include "src/core/lib/iomgr/ev_posix.h"
#include "src/core/lib/iomgr/iomgr.h"
#include "src/core/lib/iomgr/socket_factory_posix.h"
+#include "src/core/lib/iomgr/socket_utils_posix.h"
#include "test/core/util/test_config.h"
#define LOG_TEST(x) gpr_log(GPR_INFO, "%s", #x)
@@ -55,6 +56,8 @@
int rcv_buf_size = 1024;
int snd_buf_size = 1024;
+static int g_num_listeners = 1;
+
class TestGrpcUdpHandler : public GrpcUdpHandler {
public:
TestGrpcUdpHandler(grpc_fd* emfd, void* user_data)
@@ -75,6 +78,7 @@
g_number_of_reads++;
g_number_of_bytes_read += static_cast<int>(byte_count);
+ gpr_log(GPR_DEBUG, "receive %zu on handler %p", byte_count, this);
GPR_ASSERT(GRPC_LOG_IF_ERROR("pollset_kick",
grpc_pollset_kick(g_pollset, nullptr)));
gpr_mu_unlock(g_mu);
@@ -213,7 +217,8 @@
resolved_addr.len = static_cast<socklen_t>(sizeof(struct sockaddr_in));
addr->sin_family = AF_INET;
GPR_ASSERT(grpc_udp_server_add_port(s, &resolved_addr, rcv_buf_size,
- snd_buf_size, &handler_factory));
+ snd_buf_size, &handler_factory,
+ g_num_listeners));
grpc_udp_server_destroy(s, nullptr);
@@ -244,9 +249,10 @@
resolved_addr.len = static_cast<socklen_t>(sizeof(struct sockaddr_in));
addr->sin_family = AF_INET;
GPR_ASSERT(grpc_udp_server_add_port(s, &resolved_addr, rcv_buf_size,
- snd_buf_size, &handler_factory));
- GPR_ASSERT(socket_factory->number_of_socket_calls == 1);
- GPR_ASSERT(socket_factory->number_of_bind_calls == 1);
+ snd_buf_size, &handler_factory,
+ g_num_listeners));
+ GPR_ASSERT(socket_factory->number_of_socket_calls == g_num_listeners);
+ GPR_ASSERT(socket_factory->number_of_bind_calls == g_num_listeners);
grpc_udp_server_destroy(s, nullptr);
@@ -271,15 +277,16 @@
resolved_addr.len = static_cast<socklen_t>(sizeof(struct sockaddr_in));
addr->sin_family = AF_INET;
GPR_ASSERT(grpc_udp_server_add_port(s, &resolved_addr, rcv_buf_size,
- snd_buf_size, &handler_factory));
+ snd_buf_size, &handler_factory,
+ g_num_listeners));
grpc_udp_server_start(s, nullptr, 0, nullptr);
- GPR_ASSERT(g_number_of_starts == 1);
+ GPR_ASSERT(g_number_of_starts == g_num_listeners);
grpc_udp_server_destroy(s, nullptr);
/* The server had a single FD, which is orphaned exactly once in *
* grpc_udp_server_destroy. */
- GPR_ASSERT(g_number_of_orphan_calls == 1);
+ GPR_ASSERT(g_number_of_orphan_calls == g_num_listeners);
shutdown_and_destroy_pollset();
}
@@ -304,7 +311,8 @@
resolved_addr.len = static_cast<socklen_t>(sizeof(struct sockaddr_storage));
addr->ss_family = AF_INET;
GPR_ASSERT(grpc_udp_server_add_port(s, &resolved_addr, rcv_buf_size,
- snd_buf_size, &handler_factory));
+ snd_buf_size, &handler_factory,
+ g_num_listeners));
svrfd = grpc_udp_server_get_fd(s, 0);
GPR_ASSERT(svrfd >= 0);
@@ -347,13 +355,16 @@
/* The server had a single FD, which is orphaned exactly once in *
* grpc_udp_server_destroy. */
- GPR_ASSERT(g_number_of_orphan_calls == 1);
+ GPR_ASSERT(g_number_of_orphan_calls == g_num_listeners);
shutdown_and_destroy_pollset();
}
int main(int argc, char** argv) {
grpc_test_init(argc, argv);
grpc_init();
+ if (grpc_is_socket_reuse_port_supported()) {
+ g_num_listeners = 10;
+ }
{
grpc_core::ExecCtx exec_ctx;
g_pollset = static_cast<grpc_pollset*>(gpr_zalloc(grpc_pollset_size()));
diff --git a/test/core/security/BUILD b/test/core/security/BUILD
index 9db73b9..70bcc8c 100644
--- a/test/core/security/BUILD
+++ b/test/core/security/BUILD
@@ -21,6 +21,18 @@
load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer")
grpc_fuzzer(
+ name = "alts_credentials_fuzzer",
+ srcs = ["alts_credentials_fuzzer.cc"],
+ language = "C++",
+ corpus = "corpus/alts_credentials_corpus",
+ deps = [
+ "//:gpr",
+ "//:grpc",
+ "//test/core/util:grpc_test_util",
+ ],
+)
+
+grpc_fuzzer(
name = "ssl_server_fuzzer",
srcs = ["ssl_server_fuzzer.cc"],
language = "C++",
diff --git a/test/core/security/alts_credentials_fuzzer.cc b/test/core/security/alts_credentials_fuzzer.cc
new file mode 100644
index 0000000..bf18f0a
--- /dev/null
+++ b/test/core/security/alts_credentials_fuzzer.cc
@@ -0,0 +1,120 @@
+/*
+ *
+ * Copyright 2018 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.
+ *
+ */
+
+#include <string.h>
+
+#include <grpc/grpc.h>
+#include <grpc/grpc_security.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+#include "test/core/util/fuzzer_util.h"
+#include "test/core/util/memory_counters.h"
+
+#include "src/core/lib/gpr/env.h"
+#include "src/core/lib/security/credentials/alts/alts_credentials.h"
+#include "src/core/lib/security/credentials/alts/check_gcp_environment.h"
+#include "src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h"
+
+using grpc_core::testing::grpc_fuzzer_get_next_byte;
+using grpc_core::testing::grpc_fuzzer_get_next_string;
+using grpc_core::testing::input_stream;
+
+// Logging
+bool squelch = true;
+bool leak_check = true;
+
+static void dont_log(gpr_log_func_args* args) {}
+
+// Add a random number of target service accounts to client options.
+static void read_target_service_accounts(
+ input_stream* inp, grpc_alts_credentials_options* options) {
+ size_t n = grpc_fuzzer_get_next_byte(inp);
+ for (size_t i = 0; i < n; i++) {
+ char* service_account = grpc_fuzzer_get_next_string(inp, nullptr);
+ if (service_account != nullptr) {
+ grpc_alts_credentials_client_options_add_target_service_account(
+ options, service_account);
+ gpr_free(service_account);
+ }
+ }
+ // Added to improve code coverage.
+ grpc_alts_credentials_client_options_add_target_service_account(options,
+ nullptr);
+ grpc_alts_credentials_client_options_add_target_service_account(
+ nullptr, "this is service account");
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ char* grpc_trace_fuzzer = gpr_getenv("GRPC_TRACE_FUZZER");
+ if (squelch && grpc_trace_fuzzer == nullptr) {
+ gpr_set_log_function(dont_log);
+ }
+ gpr_free(grpc_trace_fuzzer);
+ struct grpc_memory_counters counters;
+ if (leak_check) {
+ grpc_memory_counters_init();
+ }
+ input_stream inp = {data, data + size};
+ grpc_init();
+ bool is_on_gcp = grpc_alts_is_running_on_gcp();
+ while (inp.cur != inp.end) {
+ bool enable_untrusted_alts = grpc_fuzzer_get_next_byte(&inp) & 0x01;
+ char* handshaker_service_url =
+ grpc_fuzzer_get_next_byte(&inp) & 0x01
+ ? grpc_fuzzer_get_next_string(&inp, nullptr)
+ : nullptr;
+ if (grpc_fuzzer_get_next_byte(&inp) & 0x01) {
+ // Test ALTS channel credentials.
+ grpc_alts_credentials_options* options =
+ grpc_alts_credentials_client_options_create();
+ read_target_service_accounts(&inp, options);
+ grpc_channel_credentials* cred = grpc_alts_credentials_create_customized(
+ options, handshaker_service_url, enable_untrusted_alts);
+ if (!enable_untrusted_alts && !is_on_gcp) {
+ GPR_ASSERT(cred == nullptr);
+ } else {
+ GPR_ASSERT(cred != nullptr);
+ }
+ grpc_channel_credentials_release(cred);
+ grpc_alts_credentials_options_destroy(options);
+ } else {
+ // Test ALTS server credentials.
+ grpc_alts_credentials_options* options =
+ grpc_alts_credentials_server_options_create();
+ grpc_server_credentials* cred =
+ grpc_alts_server_credentials_create_customized(
+ options, handshaker_service_url, enable_untrusted_alts);
+ if (!enable_untrusted_alts && !is_on_gcp) {
+ GPR_ASSERT(cred == nullptr);
+ } else {
+ GPR_ASSERT(cred != nullptr);
+ }
+ grpc_server_credentials_release(cred);
+ grpc_alts_credentials_options_destroy(options);
+ }
+ gpr_free(handshaker_service_url);
+ }
+ grpc_shutdown();
+ if (leak_check) {
+ counters = grpc_memory_counters_snapshot();
+ grpc_memory_counters_destroy();
+ GPR_ASSERT(counters.total_size_relative == 0);
+ }
+ return 0;
+}
diff --git a/test/core/security/corpus/alts_credentials_corpus/0149b46b88d583e05be0fb1423d10f2a14d36c48 b/test/core/security/corpus/alts_credentials_corpus/0149b46b88d583e05be0fb1423d10f2a14d36c48
new file mode 100644
index 0000000..c062c7f
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/0149b46b88d583e05be0fb1423d10f2a14d36c48
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/047fc351e73f760d329d5a8845944720be9ce773 b/test/core/security/corpus/alts_credentials_corpus/047fc351e73f760d329d5a8845944720be9ce773
new file mode 100644
index 0000000..d943cfe
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/047fc351e73f760d329d5a8845944720be9ce773
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/04ef96c66d8222d1a2c07e6b2a6548e6a527042b b/test/core/security/corpus/alts_credentials_corpus/04ef96c66d8222d1a2c07e6b2a6548e6a527042b
new file mode 100644
index 0000000..e7346f3
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/04ef96c66d8222d1a2c07e6b2a6548e6a527042b
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/05a7e16c1d7f92111f43e9c777421879920e79a4 b/test/core/security/corpus/alts_credentials_corpus/05a7e16c1d7f92111f43e9c777421879920e79a4
new file mode 100644
index 0000000..43b8b47
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/05a7e16c1d7f92111f43e9c777421879920e79a4
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/063eb46f202fdfe7935c30ca38d7eb81c82db419 b/test/core/security/corpus/alts_credentials_corpus/063eb46f202fdfe7935c30ca38d7eb81c82db419
new file mode 100644
index 0000000..5b30f12
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/063eb46f202fdfe7935c30ca38d7eb81c82db419
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/064773597c295fa871c184fc12d17b6de8aab31b b/test/core/security/corpus/alts_credentials_corpus/064773597c295fa871c184fc12d17b6de8aab31b
new file mode 100644
index 0000000..758709b
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/064773597c295fa871c184fc12d17b6de8aab31b
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/087449740758b114d16790067707934479946bd6 b/test/core/security/corpus/alts_credentials_corpus/087449740758b114d16790067707934479946bd6
new file mode 100644
index 0000000..099636f
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/087449740758b114d16790067707934479946bd6
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/0a5d068feb57a2782c6eba57b637abe8668ac82f b/test/core/security/corpus/alts_credentials_corpus/0a5d068feb57a2782c6eba57b637abe8668ac82f
new file mode 100644
index 0000000..fd7d7c8
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/0a5d068feb57a2782c6eba57b637abe8668ac82f
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/0b81e6d89bf7df80e87e5ee7c49f7cc1431f77e8 b/test/core/security/corpus/alts_credentials_corpus/0b81e6d89bf7df80e87e5ee7c49f7cc1431f77e8
new file mode 100644
index 0000000..a40664b
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/0b81e6d89bf7df80e87e5ee7c49f7cc1431f77e8
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/11409339cec708a5e353893101bfe76364337d5c b/test/core/security/corpus/alts_credentials_corpus/11409339cec708a5e353893101bfe76364337d5c
new file mode 100644
index 0000000..c8b350d
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/11409339cec708a5e353893101bfe76364337d5c
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/147696a264cd6f197adb7c68aff834c30b1b77f8 b/test/core/security/corpus/alts_credentials_corpus/147696a264cd6f197adb7c68aff834c30b1b77f8
new file mode 100644
index 0000000..5f68d8a
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/147696a264cd6f197adb7c68aff834c30b1b77f8
@@ -0,0 +1 @@
+ø+ú
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/160e5cac38c5c9e919ed6e4fbafee76907d63044 b/test/core/security/corpus/alts_credentials_corpus/160e5cac38c5c9e919ed6e4fbafee76907d63044
new file mode 100644
index 0000000..c11ad66
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/160e5cac38c5c9e919ed6e4fbafee76907d63044
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/173d02167db431040b0540d98f6fc5e8b456587d b/test/core/security/corpus/alts_credentials_corpus/173d02167db431040b0540d98f6fc5e8b456587d
new file mode 100644
index 0000000..662cc9b
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/173d02167db431040b0540d98f6fc5e8b456587d
@@ -0,0 +1 @@
+òÒÒ
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/18a3fe239806b3c7d1af24bcd2bd23aeeb072d5c b/test/core/security/corpus/alts_credentials_corpus/18a3fe239806b3c7d1af24bcd2bd23aeeb072d5c
new file mode 100644
index 0000000..9239e10
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/18a3fe239806b3c7d1af24bcd2bd23aeeb072d5c
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/195abd83b2e9d32b1b5b854fe33da44b6db40880 b/test/core/security/corpus/alts_credentials_corpus/195abd83b2e9d32b1b5b854fe33da44b6db40880
new file mode 100644
index 0000000..db7815e
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/195abd83b2e9d32b1b5b854fe33da44b6db40880
@@ -0,0 +1 @@
+apÿì~!õìA~;ì
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/19af2509c7d84334b9ec64de4767a07d5294fd72 b/test/core/security/corpus/alts_credentials_corpus/19af2509c7d84334b9ec64de4767a07d5294fd72
new file mode 100644
index 0000000..b87c814
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/19af2509c7d84334b9ec64de4767a07d5294fd72
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/1b9864b948fcf08b062fd4401ef55b214c259535 b/test/core/security/corpus/alts_credentials_corpus/1b9864b948fcf08b062fd4401ef55b214c259535
new file mode 100644
index 0000000..8cb97c5
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/1b9864b948fcf08b062fd4401ef55b214c259535
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/1edddfa67de854d7faaba41418fda845e9c6a89d b/test/core/security/corpus/alts_credentials_corpus/1edddfa67de854d7faaba41418fda845e9c6a89d
new file mode 100644
index 0000000..035f07c
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/1edddfa67de854d7faaba41418fda845e9c6a89d
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/20031bb00e6608e1b570aa96e6afb9de06d42167 b/test/core/security/corpus/alts_credentials_corpus/20031bb00e6608e1b570aa96e6afb9de06d42167
new file mode 100644
index 0000000..27753df
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/20031bb00e6608e1b570aa96e6afb9de06d42167
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/22b4c7ce7db99b0df63c9eae9265de484b695922 b/test/core/security/corpus/alts_credentials_corpus/22b4c7ce7db99b0df63c9eae9265de484b695922
new file mode 100644
index 0000000..ab8f18d
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/22b4c7ce7db99b0df63c9eae9265de484b695922
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/27416437ad287bd3cc1c5efdecebc39f20df73c1 b/test/core/security/corpus/alts_credentials_corpus/27416437ad287bd3cc1c5efdecebc39f20df73c1
new file mode 100644
index 0000000..c400e3e
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/27416437ad287bd3cc1c5efdecebc39f20df73c1
@@ -0,0 +1 @@
+Ä=ļyyyyyyyyyz
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/27e8cd785c2b9346f68dba75761b52fbabaf2b72 b/test/core/security/corpus/alts_credentials_corpus/27e8cd785c2b9346f68dba75761b52fbabaf2b72
new file mode 100644
index 0000000..746dee9
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/27e8cd785c2b9346f68dba75761b52fbabaf2b72
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/28236f860d3d8e5ea11176746cb4c1c5c4f1f6c0 b/test/core/security/corpus/alts_credentials_corpus/28236f860d3d8e5ea11176746cb4c1c5c4f1f6c0
new file mode 100644
index 0000000..982c97b
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/28236f860d3d8e5ea11176746cb4c1c5c4f1f6c0
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/29e15b492c5a409938092a30c003c5c34df7e283 b/test/core/security/corpus/alts_credentials_corpus/29e15b492c5a409938092a30c003c5c34df7e283
new file mode 100644
index 0000000..c3e5b25
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/29e15b492c5a409938092a30c003c5c34df7e283
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/2a47864d77749aa042b772895dbdf46f608ccc6d b/test/core/security/corpus/alts_credentials_corpus/2a47864d77749aa042b772895dbdf46f608ccc6d
new file mode 100644
index 0000000..141d94d
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/2a47864d77749aa042b772895dbdf46f608ccc6d
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/2cca5cb1b135c35f6e5e1ec4c37deb9e12d37dc0 b/test/core/security/corpus/alts_credentials_corpus/2cca5cb1b135c35f6e5e1ec4c37deb9e12d37dc0
new file mode 100644
index 0000000..a956708
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/2cca5cb1b135c35f6e5e1ec4c37deb9e12d37dc0
@@ -0,0 +1,2 @@
+ï
+ïï
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/2df27b6c42dbaee382a29a87338d64ee87354acb b/test/core/security/corpus/alts_credentials_corpus/2df27b6c42dbaee382a29a87338d64ee87354acb
new file mode 100644
index 0000000..a35f0e8
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/2df27b6c42dbaee382a29a87338d64ee87354acb
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/2e9ddd1339d8e599cef658a08965985c4f45e428 b/test/core/security/corpus/alts_credentials_corpus/2e9ddd1339d8e599cef658a08965985c4f45e428
new file mode 100644
index 0000000..17c98e7
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/2e9ddd1339d8e599cef658a08965985c4f45e428
@@ -0,0 +1,2 @@
+ï
+ïe
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/31a2d12a84a7a56ace831a9668d6ab4847390679 b/test/core/security/corpus/alts_credentials_corpus/31a2d12a84a7a56ace831a9668d6ab4847390679
new file mode 100644
index 0000000..745dc42
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/31a2d12a84a7a56ace831a9668d6ab4847390679
@@ -0,0 +1,2 @@
+ï
+ïé
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/33cb9ec0ce3538ed6079b5fcb127649a5d05955b b/test/core/security/corpus/alts_credentials_corpus/33cb9ec0ce3538ed6079b5fcb127649a5d05955b
new file mode 100644
index 0000000..2931764
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/33cb9ec0ce3538ed6079b5fcb127649a5d05955b
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/348d9ae6eebb2e1644addf7f07231d108cf6f3b8 b/test/core/security/corpus/alts_credentials_corpus/348d9ae6eebb2e1644addf7f07231d108cf6f3b8
new file mode 100644
index 0000000..02326f0
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/348d9ae6eebb2e1644addf7f07231d108cf6f3b8
@@ -0,0 +1 @@
+òÒä
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/359f76f3c802292e92b0640de2bfe051e780a3b6 b/test/core/security/corpus/alts_credentials_corpus/359f76f3c802292e92b0640de2bfe051e780a3b6
new file mode 100644
index 0000000..f31c54b
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/359f76f3c802292e92b0640de2bfe051e780a3b6
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/35a479988e965a6e3e75138b64b0bd1f45073e2f b/test/core/security/corpus/alts_credentials_corpus/35a479988e965a6e3e75138b64b0bd1f45073e2f
new file mode 100644
index 0000000..4e44bcc
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/35a479988e965a6e3e75138b64b0bd1f45073e2f
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/362b00d713686ff70cb0199f3d7d0058e5a1a27a b/test/core/security/corpus/alts_credentials_corpus/362b00d713686ff70cb0199f3d7d0058e5a1a27a
new file mode 100644
index 0000000..3e22fca
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/362b00d713686ff70cb0199f3d7d0058e5a1a27a
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/3849c1625071791ceae709b9c6c705b28d099d67 b/test/core/security/corpus/alts_credentials_corpus/3849c1625071791ceae709b9c6c705b28d099d67
new file mode 100644
index 0000000..5bc905d
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/3849c1625071791ceae709b9c6c705b28d099d67
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/39ef03c66ee2d4bcfb6c8da50486dcd40f02fb12 b/test/core/security/corpus/alts_credentials_corpus/39ef03c66ee2d4bcfb6c8da50486dcd40f02fb12
new file mode 100644
index 0000000..467004c
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/39ef03c66ee2d4bcfb6c8da50486dcd40f02fb12
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/3a3ca061863499ebc171a4f910fa1b49523baad4 b/test/core/security/corpus/alts_credentials_corpus/3a3ca061863499ebc171a4f910fa1b49523baad4
new file mode 100644
index 0000000..97f09bf
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/3a3ca061863499ebc171a4f910fa1b49523baad4
@@ -0,0 +1 @@
+úÒû9
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/3a890f3fd01b048ac9db65a9a9b4f4443268b91a b/test/core/security/corpus/alts_credentials_corpus/3a890f3fd01b048ac9db65a9a9b4f4443268b91a
new file mode 100644
index 0000000..97b05e8
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/3a890f3fd01b048ac9db65a9a9b4f4443268b91a
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/3b9554038a425bd1fae057ba41f9366bb467e946 b/test/core/security/corpus/alts_credentials_corpus/3b9554038a425bd1fae057ba41f9366bb467e946
new file mode 100644
index 0000000..d0ef634
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/3b9554038a425bd1fae057ba41f9366bb467e946
@@ -0,0 +1 @@
+ÜðððððððððððððððððððððððððððÔððððòððððððÔÜÜÜ
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/3ce0ae4aa226f205a3a4e66bbb253419d9d754bf b/test/core/security/corpus/alts_credentials_corpus/3ce0ae4aa226f205a3a4e66bbb253419d9d754bf
new file mode 100644
index 0000000..08e6df0
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/3ce0ae4aa226f205a3a4e66bbb253419d9d754bf
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/3dccc5523986c37e27684659bba8a1037e7a92e8 b/test/core/security/corpus/alts_credentials_corpus/3dccc5523986c37e27684659bba8a1037e7a92e8
new file mode 100644
index 0000000..09b735e
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/3dccc5523986c37e27684659bba8a1037e7a92e8
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/3e0908c15b1cede4541d25f388b1345e8641e221 b/test/core/security/corpus/alts_credentials_corpus/3e0908c15b1cede4541d25f388b1345e8641e221
new file mode 100644
index 0000000..eabd458
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/3e0908c15b1cede4541d25f388b1345e8641e221
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/3fcb181ff6a8c8e2ba38ed34cf78f7482eb55cb7 b/test/core/security/corpus/alts_credentials_corpus/3fcb181ff6a8c8e2ba38ed34cf78f7482eb55cb7
new file mode 100644
index 0000000..bbef93b
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/3fcb181ff6a8c8e2ba38ed34cf78f7482eb55cb7
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/41c9b5f720eb8f8fa04c840375a881781a849b43 b/test/core/security/corpus/alts_credentials_corpus/41c9b5f720eb8f8fa04c840375a881781a849b43
new file mode 100644
index 0000000..d611c73
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/41c9b5f720eb8f8fa04c840375a881781a849b43
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/4257a018f08f13a3a9adc848ef808e1be50bc4cf b/test/core/security/corpus/alts_credentials_corpus/4257a018f08f13a3a9adc848ef808e1be50bc4cf
new file mode 100644
index 0000000..607c971
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/4257a018f08f13a3a9adc848ef808e1be50bc4cf
@@ -0,0 +1,2 @@
+òÓ99999999999999999999999999999999999¬¬¬¬¬¬¬¬¬ÿÿÿÿÿÿÿÿÿÿÿÿÿ/////ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
+ÿÿÿÿÿÿÿÿÿÿ²²²²²²²ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿNSt6locale5
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/42dfc5c4d13261b7259e65cd692df9c9d607194e b/test/core/security/corpus/alts_credentials_corpus/42dfc5c4d13261b7259e65cd692df9c9d607194e
new file mode 100644
index 0000000..48ffa85
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/42dfc5c4d13261b7259e65cd692df9c9d607194e
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/43144664aedb585d45d42aa5249ddbfe81afe470 b/test/core/security/corpus/alts_credentials_corpus/43144664aedb585d45d42aa5249ddbfe81afe470
new file mode 100644
index 0000000..fee2672
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/43144664aedb585d45d42aa5249ddbfe81afe470
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/43e5ad495a47593b17dbcbd3e70c2e25a417bb6e b/test/core/security/corpus/alts_credentials_corpus/43e5ad495a47593b17dbcbd3e70c2e25a417bb6e
new file mode 100644
index 0000000..32ffc96
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/43e5ad495a47593b17dbcbd3e70c2e25a417bb6e
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/446614e45b7bef49118b17e031c48faf167ebe3e b/test/core/security/corpus/alts_credentials_corpus/446614e45b7bef49118b17e031c48faf167ebe3e
new file mode 100644
index 0000000..849aadf
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/446614e45b7bef49118b17e031c48faf167ebe3e
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/46492477fa84ca88e85df914801af0b09b0939f6 b/test/core/security/corpus/alts_credentials_corpus/46492477fa84ca88e85df914801af0b09b0939f6
new file mode 100644
index 0000000..98885bc
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/46492477fa84ca88e85df914801af0b09b0939f6
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/47157f83b166b57e0052c98a65c6db864fa6cb9b b/test/core/security/corpus/alts_credentials_corpus/47157f83b166b57e0052c98a65c6db864fa6cb9b
new file mode 100644
index 0000000..fad1e0f
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/47157f83b166b57e0052c98a65c6db864fa6cb9b
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/473fc9b6d768a925527d3ad805ca363d490dc741 b/test/core/security/corpus/alts_credentials_corpus/473fc9b6d768a925527d3ad805ca363d490dc741
new file mode 100644
index 0000000..1775a17
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/473fc9b6d768a925527d3ad805ca363d490dc741
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/483c0b4015100eee00f6b23d1100d8c4953dd3b1 b/test/core/security/corpus/alts_credentials_corpus/483c0b4015100eee00f6b23d1100d8c4953dd3b1
new file mode 100644
index 0000000..2d52687
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/483c0b4015100eee00f6b23d1100d8c4953dd3b1
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/48be2dc4cdc5462407b319caa855d976cda88153 b/test/core/security/corpus/alts_credentials_corpus/48be2dc4cdc5462407b319caa855d976cda88153
new file mode 100644
index 0000000..c1c2cd9
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/48be2dc4cdc5462407b319caa855d976cda88153
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/4e84eb54a0e438052b0c2e83653135042d9eb59a b/test/core/security/corpus/alts_credentials_corpus/4e84eb54a0e438052b0c2e83653135042d9eb59a
new file mode 100644
index 0000000..66b525f
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/4e84eb54a0e438052b0c2e83653135042d9eb59a
@@ -0,0 +1 @@
+òÒ
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/50839d5c8bf33f0970986dcc4b73b024f11a95b7 b/test/core/security/corpus/alts_credentials_corpus/50839d5c8bf33f0970986dcc4b73b024f11a95b7
new file mode 100644
index 0000000..9673f73
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/50839d5c8bf33f0970986dcc4b73b024f11a95b7
@@ -0,0 +1 @@
+òÿt_Ó ÿÿÿÿÿæææ&ææææææææææææææææææææææÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿÿÿÜ
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/523d964986d8ad966ae07e540a608681098813f9 b/test/core/security/corpus/alts_credentials_corpus/523d964986d8ad966ae07e540a608681098813f9
new file mode 100644
index 0000000..06e05df
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/523d964986d8ad966ae07e540a608681098813f9
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/5410b8190c95dacd36d6e6ec75b7538a630e08de b/test/core/security/corpus/alts_credentials_corpus/5410b8190c95dacd36d6e6ec75b7538a630e08de
new file mode 100644
index 0000000..4579c6f
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/5410b8190c95dacd36d6e6ec75b7538a630e08de
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/549b2891ac79f504a7c9ea00f6d7527c34ce04e6 b/test/core/security/corpus/alts_credentials_corpus/549b2891ac79f504a7c9ea00f6d7527c34ce04e6
new file mode 100644
index 0000000..6f1a9ed
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/549b2891ac79f504a7c9ea00f6d7527c34ce04e6
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/55321649e7b7f1b5664ae20724e683c930643fc4 b/test/core/security/corpus/alts_credentials_corpus/55321649e7b7f1b5664ae20724e683c930643fc4
new file mode 100644
index 0000000..e38fd28
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/55321649e7b7f1b5664ae20724e683c930643fc4
@@ -0,0 +1 @@
+ò)Ò
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/55cc52f25865baee3e6e52c3110a9723caa2b3cb b/test/core/security/corpus/alts_credentials_corpus/55cc52f25865baee3e6e52c3110a9723caa2b3cb
new file mode 100644
index 0000000..aae2fe5
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/55cc52f25865baee3e6e52c3110a9723caa2b3cb
@@ -0,0 +1 @@
+òÒÎ
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/56c22410e3295ad03aa31552ab888f581756cc17 b/test/core/security/corpus/alts_credentials_corpus/56c22410e3295ad03aa31552ab888f581756cc17
new file mode 100644
index 0000000..e5d7cf9
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/56c22410e3295ad03aa31552ab888f581756cc17
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/5724a705b62a7548ba2df1abe4ef0c970c4e1bd2 b/test/core/security/corpus/alts_credentials_corpus/5724a705b62a7548ba2df1abe4ef0c970c4e1bd2
new file mode 100644
index 0000000..b0875c9
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/5724a705b62a7548ba2df1abe4ef0c970c4e1bd2
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/576a148c107d56861d1611641a6f7c7921061c5c b/test/core/security/corpus/alts_credentials_corpus/576a148c107d56861d1611641a6f7c7921061c5c
new file mode 100644
index 0000000..6d91b58
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/576a148c107d56861d1611641a6f7c7921061c5c
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/5a6b8263e8939f851cf5b1e347a33d97253b7b3d b/test/core/security/corpus/alts_credentials_corpus/5a6b8263e8939f851cf5b1e347a33d97253b7b3d
new file mode 100644
index 0000000..add56ca
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/5a6b8263e8939f851cf5b1e347a33d97253b7b3d
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/5ba93c9db0cff93f52b521d7420e43f6eda2784f b/test/core/security/corpus/alts_credentials_corpus/5ba93c9db0cff93f52b521d7420e43f6eda2784f
new file mode 100644
index 0000000..f76dd23
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/5ba93c9db0cff93f52b521d7420e43f6eda2784f
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/5bd02a339fd7705449388580c75bfcc597aba954 b/test/core/security/corpus/alts_credentials_corpus/5bd02a339fd7705449388580c75bfcc597aba954
new file mode 100644
index 0000000..f450932
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/5bd02a339fd7705449388580c75bfcc597aba954
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/5bd6fb6fc4163bf3a9db6ddaf509dce8df8a5000 b/test/core/security/corpus/alts_credentials_corpus/5bd6fb6fc4163bf3a9db6ddaf509dce8df8a5000
new file mode 100644
index 0000000..aea3da6
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/5bd6fb6fc4163bf3a9db6ddaf509dce8df8a5000
@@ -0,0 +1 @@
+)applea.ÿÿÿÿÜÜ.ÿßÿÿÿÿÿÜÿÿÿÜÿÿÜÜ.
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/5d06fc38005503af3d084721c60e574fb9d2f370 b/test/core/security/corpus/alts_credentials_corpus/5d06fc38005503af3d084721c60e574fb9d2f370
new file mode 100644
index 0000000..42eb673
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/5d06fc38005503af3d084721c60e574fb9d2f370
@@ -0,0 +1 @@
+ÓÓ×
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/5ddc10489ff3269bdaa3051b70fb7af455ee1104 b/test/core/security/corpus/alts_credentials_corpus/5ddc10489ff3269bdaa3051b70fb7af455ee1104
new file mode 100644
index 0000000..79db88a
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/5ddc10489ff3269bdaa3051b70fb7af455ee1104
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/5ea9d515f0d10b04f1356b9463139bfe121a6e4a b/test/core/security/corpus/alts_credentials_corpus/5ea9d515f0d10b04f1356b9463139bfe121a6e4a
new file mode 100644
index 0000000..7efb47e
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/5ea9d515f0d10b04f1356b9463139bfe121a6e4a
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/61c449793347cf2e1ed0c38d54d23c63dfaabeb8 b/test/core/security/corpus/alts_credentials_corpus/61c449793347cf2e1ed0c38d54d23c63dfaabeb8
new file mode 100644
index 0000000..96031be
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/61c449793347cf2e1ed0c38d54d23c63dfaabeb8
@@ -0,0 +1 @@
+òÿÿÿÿÿÿÿÿÿÿÿÿÿÿÝÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/6287389c373e9788dcc04f9747b4be1fd1ef3028 b/test/core/security/corpus/alts_credentials_corpus/6287389c373e9788dcc04f9747b4be1fd1ef3028
new file mode 100644
index 0000000..799bd0e
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/6287389c373e9788dcc04f9747b4be1fd1ef3028
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/64d4de4d5aafab7ec388a7fe83066c1a4d1d9d68 b/test/core/security/corpus/alts_credentials_corpus/64d4de4d5aafab7ec388a7fe83066c1a4d1d9d68
new file mode 100644
index 0000000..2e91965
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/64d4de4d5aafab7ec388a7fe83066c1a4d1d9d68
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/651c37806d2ac579dcfc97643c3c1ea74dbb8774 b/test/core/security/corpus/alts_credentials_corpus/651c37806d2ac579dcfc97643c3c1ea74dbb8774
new file mode 100644
index 0000000..618e514
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/651c37806d2ac579dcfc97643c3c1ea74dbb8774
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/6551d02d20573cfa2944ec1f12b0c01f264a1326 b/test/core/security/corpus/alts_credentials_corpus/6551d02d20573cfa2944ec1f12b0c01f264a1326
new file mode 100644
index 0000000..98056c0
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/6551d02d20573cfa2944ec1f12b0c01f264a1326
@@ -0,0 +1 @@
+s
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/65f029414ee10e45ff4b9f305f7b472364cea538 b/test/core/security/corpus/alts_credentials_corpus/65f029414ee10e45ff4b9f305f7b472364cea538
new file mode 100644
index 0000000..1c3a1a0
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/65f029414ee10e45ff4b9f305f7b472364cea538
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/68b75a17fe2db060df3e61a597650ba99079abbf b/test/core/security/corpus/alts_credentials_corpus/68b75a17fe2db060df3e61a597650ba99079abbf
new file mode 100644
index 0000000..327dd39
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/68b75a17fe2db060df3e61a597650ba99079abbf
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/69e80594dbc5c4c648e39883a650b1760f20ab63 b/test/core/security/corpus/alts_credentials_corpus/69e80594dbc5c4c648e39883a650b1760f20ab63
new file mode 100644
index 0000000..740b987
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/69e80594dbc5c4c648e39883a650b1760f20ab63
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/6cb47d0e640b4c41e32f13c0d64ee46eae1b80b5 b/test/core/security/corpus/alts_credentials_corpus/6cb47d0e640b4c41e32f13c0d64ee46eae1b80b5
new file mode 100644
index 0000000..b22a010
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/6cb47d0e640b4c41e32f13c0d64ee46eae1b80b5
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/6da5fe063432cb9094c7c083efdbbe5ba4246d18 b/test/core/security/corpus/alts_credentials_corpus/6da5fe063432cb9094c7c083efdbbe5ba4246d18
new file mode 100644
index 0000000..993620e
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/6da5fe063432cb9094c7c083efdbbe5ba4246d18
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/6dd140da774d85f272fb587dc1b2a85d881a7c21 b/test/core/security/corpus/alts_credentials_corpus/6dd140da774d85f272fb587dc1b2a85d881a7c21
new file mode 100644
index 0000000..d838739
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/6dd140da774d85f272fb587dc1b2a85d881a7c21
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/6ddab273597d73be49e2307d68e00fa18bba4765 b/test/core/security/corpus/alts_credentials_corpus/6ddab273597d73be49e2307d68e00fa18bba4765
new file mode 100644
index 0000000..3e74467
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/6ddab273597d73be49e2307d68e00fa18bba4765
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/6eaf85d84fbf47ea0619d0dba8d366f4e3ff0be6 b/test/core/security/corpus/alts_credentials_corpus/6eaf85d84fbf47ea0619d0dba8d366f4e3ff0be6
new file mode 100644
index 0000000..42cddf7
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/6eaf85d84fbf47ea0619d0dba8d366f4e3ff0be6
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/6f751cc09af8113f6ecd491b1830bd8454c4738d b/test/core/security/corpus/alts_credentials_corpus/6f751cc09af8113f6ecd491b1830bd8454c4738d
new file mode 100644
index 0000000..a51a3d0
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/6f751cc09af8113f6ecd491b1830bd8454c4738d
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/70d9eb29a70d483d07e2faca6b00098af78d1fff b/test/core/security/corpus/alts_credentials_corpus/70d9eb29a70d483d07e2faca6b00098af78d1fff
new file mode 100644
index 0000000..e9fb9b9
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/70d9eb29a70d483d07e2faca6b00098af78d1fff
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/7192effa1058382b379fb7b87f1acad5ac554d05 b/test/core/security/corpus/alts_credentials_corpus/7192effa1058382b379fb7b87f1acad5ac554d05
new file mode 100644
index 0000000..23a3819
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/7192effa1058382b379fb7b87f1acad5ac554d05
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/730e85d6a62e70cb6721009b903782ade4ff73a2 b/test/core/security/corpus/alts_credentials_corpus/730e85d6a62e70cb6721009b903782ade4ff73a2
new file mode 100644
index 0000000..9c1e71c
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/730e85d6a62e70cb6721009b903782ade4ff73a2
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/74002471a854059cb29de7cad8f9fb7adc3c5ec2 b/test/core/security/corpus/alts_credentials_corpus/74002471a854059cb29de7cad8f9fb7adc3c5ec2
new file mode 100644
index 0000000..bb83231
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/74002471a854059cb29de7cad8f9fb7adc3c5ec2
@@ -0,0 +1,2 @@
+
+¡
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/747f2330cd1fc4a06d54b376a9a6528d0364f0ac b/test/core/security/corpus/alts_credentials_corpus/747f2330cd1fc4a06d54b376a9a6528d0364f0ac
new file mode 100644
index 0000000..332ac4b
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/747f2330cd1fc4a06d54b376a9a6528d0364f0ac
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/749d5d7a9e0b1545b297117e834462af32b3e230 b/test/core/security/corpus/alts_credentials_corpus/749d5d7a9e0b1545b297117e834462af32b3e230
new file mode 100644
index 0000000..a00db59
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/749d5d7a9e0b1545b297117e834462af32b3e230
@@ -0,0 +1 @@
+aèÿÿ+
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/77de0b1de120ac702ca45868b1008a48626daf12 b/test/core/security/corpus/alts_credentials_corpus/77de0b1de120ac702ca45868b1008a48626daf12
new file mode 100644
index 0000000..352762c
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/77de0b1de120ac702ca45868b1008a48626daf12
@@ -0,0 +1 @@
+òÒ^
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/792c67398bce19a4eeda32653c994436e79456e5 b/test/core/security/corpus/alts_credentials_corpus/792c67398bce19a4eeda32653c994436e79456e5
new file mode 100644
index 0000000..0834287
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/792c67398bce19a4eeda32653c994436e79456e5
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/7a3022b248c8960289e4c80c7cc8df409499e5da b/test/core/security/corpus/alts_credentials_corpus/7a3022b248c8960289e4c80c7cc8df409499e5da
new file mode 100644
index 0000000..f9ef6a4
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/7a3022b248c8960289e4c80c7cc8df409499e5da
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/7a9372081294a6fbd3fecdd91b99589c98d4948e b/test/core/security/corpus/alts_credentials_corpus/7a9372081294a6fbd3fecdd91b99589c98d4948e
new file mode 100644
index 0000000..7100f32
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/7a9372081294a6fbd3fecdd91b99589c98d4948e
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/7bbe4ba828947550f4ad089d5989cb695ecbdb1b b/test/core/security/corpus/alts_credentials_corpus/7bbe4ba828947550f4ad089d5989cb695ecbdb1b
new file mode 100644
index 0000000..44e3963
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/7bbe4ba828947550f4ad089d5989cb695ecbdb1b
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/7f1ad514a96f0c3d5ca5d6f7880b929a65eeae96 b/test/core/security/corpus/alts_credentials_corpus/7f1ad514a96f0c3d5ca5d6f7880b929a65eeae96
new file mode 100644
index 0000000..700c079
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/7f1ad514a96f0c3d5ca5d6f7880b929a65eeae96
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/7f2b075f0b6707c38db851747e2578343eeab286 b/test/core/security/corpus/alts_credentials_corpus/7f2b075f0b6707c38db851747e2578343eeab286
new file mode 100644
index 0000000..1f7b5d7
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/7f2b075f0b6707c38db851747e2578343eeab286
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/81ebc64bfde3fad37af5a58ef7f1c5c3c54c4b5d b/test/core/security/corpus/alts_credentials_corpus/81ebc64bfde3fad37af5a58ef7f1c5c3c54c4b5d
new file mode 100644
index 0000000..d89f30f
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/81ebc64bfde3fad37af5a58ef7f1c5c3c54c4b5d
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/82fae081afaea13831404024d39658344d56e1c6 b/test/core/security/corpus/alts_credentials_corpus/82fae081afaea13831404024d39658344d56e1c6
new file mode 100644
index 0000000..bc3cfc2
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/82fae081afaea13831404024d39658344d56e1c6
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/83ba41cea1adab707f7f213af5e2ed734bdddc25 b/test/core/security/corpus/alts_credentials_corpus/83ba41cea1adab707f7f213af5e2ed734bdddc25
new file mode 100644
index 0000000..d465fb4
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/83ba41cea1adab707f7f213af5e2ed734bdddc25
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/841a3f66c94e5acd836a44cd5a8514d4ad45d83e b/test/core/security/corpus/alts_credentials_corpus/841a3f66c94e5acd836a44cd5a8514d4ad45d83e
new file mode 100644
index 0000000..cbb7bdc
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/841a3f66c94e5acd836a44cd5a8514d4ad45d83e
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/841ef94ee0f1b0b45983d95b75aba25421d73f2c b/test/core/security/corpus/alts_credentials_corpus/841ef94ee0f1b0b45983d95b75aba25421d73f2c
new file mode 100644
index 0000000..ba85d1d
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/841ef94ee0f1b0b45983d95b75aba25421d73f2c
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/843b0aad4a9707c5dcc92d12d876b78675cfcb65 b/test/core/security/corpus/alts_credentials_corpus/843b0aad4a9707c5dcc92d12d876b78675cfcb65
new file mode 100644
index 0000000..02d61c5
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/843b0aad4a9707c5dcc92d12d876b78675cfcb65
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/8483e3d92eda8df504b1d1d0d012f4bcd778cd33 b/test/core/security/corpus/alts_credentials_corpus/8483e3d92eda8df504b1d1d0d012f4bcd778cd33
new file mode 100644
index 0000000..3795466
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/8483e3d92eda8df504b1d1d0d012f4bcd778cd33
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/876830fdff4e59038fa2173b700faef5bffe61de b/test/core/security/corpus/alts_credentials_corpus/876830fdff4e59038fa2173b700faef5bffe61de
new file mode 100644
index 0000000..26048bd
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/876830fdff4e59038fa2173b700faef5bffe61de
@@ -0,0 +1 @@
+òÒA
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/87ca3342fdce0c1f678a3f1b62428032ef51442d b/test/core/security/corpus/alts_credentials_corpus/87ca3342fdce0c1f678a3f1b62428032ef51442d
new file mode 100644
index 0000000..ea35b45
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/87ca3342fdce0c1f678a3f1b62428032ef51442d
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/87d044027cdb7d35fadb56532f497764246946a6 b/test/core/security/corpus/alts_credentials_corpus/87d044027cdb7d35fadb56532f497764246946a6
new file mode 100644
index 0000000..1e474c9
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/87d044027cdb7d35fadb56532f497764246946a6
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/88ce75ba18bdb7e93a81197d850f4e792f6a8155 b/test/core/security/corpus/alts_credentials_corpus/88ce75ba18bdb7e93a81197d850f4e792f6a8155
new file mode 100644
index 0000000..70c9ab1
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/88ce75ba18bdb7e93a81197d850f4e792f6a8155
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/89dc55e8e20e811e78c952c8bd2c16f55fe72f57 b/test/core/security/corpus/alts_credentials_corpus/89dc55e8e20e811e78c952c8bd2c16f55fe72f57
new file mode 100644
index 0000000..00961fd
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/89dc55e8e20e811e78c952c8bd2c16f55fe72f57
@@ -0,0 +1 @@
+òÒ
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/8a215a58908f44bdced595ceb01a81977f1d72f0 b/test/core/security/corpus/alts_credentials_corpus/8a215a58908f44bdced595ceb01a81977f1d72f0
new file mode 100644
index 0000000..296f8b7
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/8a215a58908f44bdced595ceb01a81977f1d72f0
@@ -0,0 +1 @@
+Ä=ÒÄ=)ÄÄÄÄÄÄ
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/8ac7459e918304ca40b1cf29a3ac0f555eada678 b/test/core/security/corpus/alts_credentials_corpus/8ac7459e918304ca40b1cf29a3ac0f555eada678
new file mode 100644
index 0000000..629a6f9
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/8ac7459e918304ca40b1cf29a3ac0f555eada678
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/8b93e50a911f3ea0e0b0377ba4636574f2ee9a5e b/test/core/security/corpus/alts_credentials_corpus/8b93e50a911f3ea0e0b0377ba4636574f2ee9a5e
new file mode 100644
index 0000000..280aecf
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/8b93e50a911f3ea0e0b0377ba4636574f2ee9a5e
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/8c9ec0ffd803505772693833d56e7a02110645b3 b/test/core/security/corpus/alts_credentials_corpus/8c9ec0ffd803505772693833d56e7a02110645b3
new file mode 100644
index 0000000..3bd046b
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/8c9ec0ffd803505772693833d56e7a02110645b3
@@ -0,0 +1 @@
+K]//(
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/8e4b361a530dc6825afcfb4106bd482c3fd010fa b/test/core/security/corpus/alts_credentials_corpus/8e4b361a530dc6825afcfb4106bd482c3fd010fa
new file mode 100644
index 0000000..3733df9
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/8e4b361a530dc6825afcfb4106bd482c3fd010fa
@@ -0,0 +1 @@
+òÒÝ
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/8f6690d97bcda890f2a5b2930a2b7a4d7b56c6e7 b/test/core/security/corpus/alts_credentials_corpus/8f6690d97bcda890f2a5b2930a2b7a4d7b56c6e7
new file mode 100644
index 0000000..7885e1ef
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/8f6690d97bcda890f2a5b2930a2b7a4d7b56c6e7
@@ -0,0 +1 @@
+òÒÝ
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/917636de2c14dce2580d4308249a94d61d62c305 b/test/core/security/corpus/alts_credentials_corpus/917636de2c14dce2580d4308249a94d61d62c305
new file mode 100644
index 0000000..cccb20d
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/917636de2c14dce2580d4308249a94d61d62c305
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/91f11008defda918951bda868cc68c6373fb0e6a b/test/core/security/corpus/alts_credentials_corpus/91f11008defda918951bda868cc68c6373fb0e6a
new file mode 100644
index 0000000..bf10853
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/91f11008defda918951bda868cc68c6373fb0e6a
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/92e01a34047b660a798086d55a3d8d7100a01939 b/test/core/security/corpus/alts_credentials_corpus/92e01a34047b660a798086d55a3d8d7100a01939
new file mode 100644
index 0000000..e86bc1d
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/92e01a34047b660a798086d55a3d8d7100a01939
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/963fafadb4de09dee0e6a852bd61b1740039a465 b/test/core/security/corpus/alts_credentials_corpus/963fafadb4de09dee0e6a852bd61b1740039a465
new file mode 100644
index 0000000..8933b18
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/963fafadb4de09dee0e6a852bd61b1740039a465
@@ -0,0 +1 @@
+ê
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/97bf33ec97b93fcc2449431915911a55b906e3b6 b/test/core/security/corpus/alts_credentials_corpus/97bf33ec97b93fcc2449431915911a55b906e3b6
new file mode 100644
index 0000000..8101e37
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/97bf33ec97b93fcc2449431915911a55b906e3b6
@@ -0,0 +1 @@
+òÓÓÒ
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/99e31e12b02b02479d10b2c08426906bd93a0840 b/test/core/security/corpus/alts_credentials_corpus/99e31e12b02b02479d10b2c08426906bd93a0840
new file mode 100644
index 0000000..9fe2a6a
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/99e31e12b02b02479d10b2c08426906bd93a0840
@@ -0,0 +1 @@
+òÓÓÒ
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/9a75ce693e7259d4d3bb9203dfc0a65f8bbaa466 b/test/core/security/corpus/alts_credentials_corpus/9a75ce693e7259d4d3bb9203dfc0a65f8bbaa466
new file mode 100644
index 0000000..5366cdd
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/9a75ce693e7259d4d3bb9203dfc0a65f8bbaa466
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/9ac0d956f9743e026baad7319ba2a75d9f1a534f b/test/core/security/corpus/alts_credentials_corpus/9ac0d956f9743e026baad7319ba2a75d9f1a534f
new file mode 100644
index 0000000..adb0583
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/9ac0d956f9743e026baad7319ba2a75d9f1a534f
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/9ae56d4451dd3e1b66ddc250d84dbf6d8cae0dbd b/test/core/security/corpus/alts_credentials_corpus/9ae56d4451dd3e1b66ddc250d84dbf6d8cae0dbd
new file mode 100644
index 0000000..121d0cb
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/9ae56d4451dd3e1b66ddc250d84dbf6d8cae0dbd
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/9b9a3a1e4023c9b172060249752a482a3437ef2a b/test/core/security/corpus/alts_credentials_corpus/9b9a3a1e4023c9b172060249752a482a3437ef2a
new file mode 100644
index 0000000..0b19f19
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/9b9a3a1e4023c9b172060249752a482a3437ef2a
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/9c81164e10bf612c352dca3ecabf57743b451d42 b/test/core/security/corpus/alts_credentials_corpus/9c81164e10bf612c352dca3ecabf57743b451d42
new file mode 100644
index 0000000..1cae116
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/9c81164e10bf612c352dca3ecabf57743b451d42
@@ -0,0 +1,2 @@
+
+z
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/9d8b420b5d32deb0140ab91eeebba58ca6163722 b/test/core/security/corpus/alts_credentials_corpus/9d8b420b5d32deb0140ab91eeebba58ca6163722
new file mode 100644
index 0000000..6d0f809
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/9d8b420b5d32deb0140ab91eeebba58ca6163722
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/9de687bf1e2cfac54c3b2e2eb85b53014a460ff7 b/test/core/security/corpus/alts_credentials_corpus/9de687bf1e2cfac54c3b2e2eb85b53014a460ff7
new file mode 100644
index 0000000..789f59c
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/9de687bf1e2cfac54c3b2e2eb85b53014a460ff7
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/9f3cda19a186bd11bfac361b464f92daa129a33b b/test/core/security/corpus/alts_credentials_corpus/9f3cda19a186bd11bfac361b464f92daa129a33b
new file mode 100644
index 0000000..61347c3
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/9f3cda19a186bd11bfac361b464f92daa129a33b
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/a14fc6a608121f8abf0fe25cf466720f00f25653 b/test/core/security/corpus/alts_credentials_corpus/a14fc6a608121f8abf0fe25cf466720f00f25653
new file mode 100644
index 0000000..58af762
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/a14fc6a608121f8abf0fe25cf466720f00f25653
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/a39906074669a6b76a35b0adf2bf36ad751f3b35 b/test/core/security/corpus/alts_credentials_corpus/a39906074669a6b76a35b0adf2bf36ad751f3b35
new file mode 100644
index 0000000..e10cdb9
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/a39906074669a6b76a35b0adf2bf36ad751f3b35
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/a454ca483b4a66b83826d061be2859dd79ff0d6c b/test/core/security/corpus/alts_credentials_corpus/a454ca483b4a66b83826d061be2859dd79ff0d6c
new file mode 100644
index 0000000..38424fc
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/a454ca483b4a66b83826d061be2859dd79ff0d6c
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/a52df5607370ff0f56d821000f3d5e386a01d489 b/test/core/security/corpus/alts_credentials_corpus/a52df5607370ff0f56d821000f3d5e386a01d489
new file mode 100644
index 0000000..f16da07
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/a52df5607370ff0f56d821000f3d5e386a01d489
@@ -0,0 +1 @@
+úÒû;
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/a56eaf47f7c7263e53efdc55ec39063dbb4ae71c b/test/core/security/corpus/alts_credentials_corpus/a56eaf47f7c7263e53efdc55ec39063dbb4ae71c
new file mode 100644
index 0000000..3664ce0
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/a56eaf47f7c7263e53efdc55ec39063dbb4ae71c
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/a79249fb8f7d53f0a280359d2d9df31594adbdfc b/test/core/security/corpus/alts_credentials_corpus/a79249fb8f7d53f0a280359d2d9df31594adbdfc
new file mode 100644
index 0000000..d7f1f45
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/a79249fb8f7d53f0a280359d2d9df31594adbdfc
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/aa98a46f25004f7436aadb36ff8b7f07ed7bfce1 b/test/core/security/corpus/alts_credentials_corpus/aa98a46f25004f7436aadb36ff8b7f07ed7bfce1
new file mode 100644
index 0000000..f1db8d9
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/aa98a46f25004f7436aadb36ff8b7f07ed7bfce1
@@ -0,0 +1 @@
+ap/òÒ+
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/adc83b19e793491b1c6ea0fd8b46cd9f32e592fc b/test/core/security/corpus/alts_credentials_corpus/adc83b19e793491b1c6ea0fd8b46cd9f32e592fc
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/adc83b19e793491b1c6ea0fd8b46cd9f32e592fc
@@ -0,0 +1 @@
+
diff --git a/test/core/security/corpus/alts_credentials_corpus/afd8e19f7bfd6c963f1856be59b75627864821dc b/test/core/security/corpus/alts_credentials_corpus/afd8e19f7bfd6c963f1856be59b75627864821dc
new file mode 100644
index 0000000..385405e
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/afd8e19f7bfd6c963f1856be59b75627864821dc
@@ -0,0 +1,2 @@
+¯+ú
+ä´õ
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/b3966239b8568442baecbeb0f8a1aa29dcdfd7ed b/test/core/security/corpus/alts_credentials_corpus/b3966239b8568442baecbeb0f8a1aa29dcdfd7ed
new file mode 100644
index 0000000..3d9fb86
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/b3966239b8568442baecbeb0f8a1aa29dcdfd7ed
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/b430d41ef65493b3e917182c23ce90df983e01ab b/test/core/security/corpus/alts_credentials_corpus/b430d41ef65493b3e917182c23ce90df983e01ab
new file mode 100644
index 0000000..cbb8ceb
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/b430d41ef65493b3e917182c23ce90df983e01ab
@@ -0,0 +1,2 @@
+ÿ
+
diff --git a/test/core/security/corpus/alts_credentials_corpus/b44e715e0cfe05f0c92a9e000ac3c36aae17df9d b/test/core/security/corpus/alts_credentials_corpus/b44e715e0cfe05f0c92a9e000ac3c36aae17df9d
new file mode 100644
index 0000000..f0b1381
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/b44e715e0cfe05f0c92a9e000ac3c36aae17df9d
@@ -0,0 +1 @@
+]]
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/b4cf4ef7b3f64eff76cf99091fddc04411774708 b/test/core/security/corpus/alts_credentials_corpus/b4cf4ef7b3f64eff76cf99091fddc04411774708
new file mode 100644
index 0000000..65d4adb
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/b4cf4ef7b3f64eff76cf99091fddc04411774708
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/b53d84468ea93620a9824ca65acf1179f431e763 b/test/core/security/corpus/alts_credentials_corpus/b53d84468ea93620a9824ca65acf1179f431e763
new file mode 100644
index 0000000..5844d31
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/b53d84468ea93620a9824ca65acf1179f431e763
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/b6ac4831cc5baabee9c8ab9af9ca3923f91097a0 b/test/core/security/corpus/alts_credentials_corpus/b6ac4831cc5baabee9c8ab9af9ca3923f91097a0
new file mode 100644
index 0000000..3d54a26
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/b6ac4831cc5baabee9c8ab9af9ca3923f91097a0
@@ -0,0 +1,2 @@
+îÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿAï
+ïé
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/b7f4a484866a8050dbc63bc905c9803c6964eda5 b/test/core/security/corpus/alts_credentials_corpus/b7f4a484866a8050dbc63bc905c9803c6964eda5
new file mode 100644
index 0000000..e17c966
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/b7f4a484866a8050dbc63bc905c9803c6964eda5
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/b8f21e59f90431c982d5ec3fb54ae4605f102252 b/test/core/security/corpus/alts_credentials_corpus/b8f21e59f90431c982d5ec3fb54ae4605f102252
new file mode 100644
index 0000000..79e3486
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/b8f21e59f90431c982d5ec3fb54ae4605f102252
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/bad10b6581cdead8e7cb96e4f544dcf0ea650fbc b/test/core/security/corpus/alts_credentials_corpus/bad10b6581cdead8e7cb96e4f544dcf0ea650fbc
new file mode 100644
index 0000000..9deb760
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/bad10b6581cdead8e7cb96e4f544dcf0ea650fbc
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/bb01bed86b43257be9f527388e1183f52438c473 b/test/core/security/corpus/alts_credentials_corpus/bb01bed86b43257be9f527388e1183f52438c473
new file mode 100644
index 0000000..ad47d46
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/bb01bed86b43257be9f527388e1183f52438c473
@@ -0,0 +1 @@
+òÒûþ
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/bb7497b00f0d999ef39dbf81c6bd0441e32723b6 b/test/core/security/corpus/alts_credentials_corpus/bb7497b00f0d999ef39dbf81c6bd0441e32723b6
new file mode 100644
index 0000000..3b2f108
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/bb7497b00f0d999ef39dbf81c6bd0441e32723b6
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/bf01b72e635deda1b4a8468f1cc36f01a54e1338 b/test/core/security/corpus/alts_credentials_corpus/bf01b72e635deda1b4a8468f1cc36f01a54e1338
new file mode 100644
index 0000000..7fa6cf8
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/bf01b72e635deda1b4a8468f1cc36f01a54e1338
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/bf8b4530d8d246dd74ac53a13471bba17941dff7 b/test/core/security/corpus/alts_credentials_corpus/bf8b4530d8d246dd74ac53a13471bba17941dff7
new file mode 100644
index 0000000..6b2aaa7
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/bf8b4530d8d246dd74ac53a13471bba17941dff7
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/c08bc84ab6a512b901bb730beb05c8394e4f1c5d b/test/core/security/corpus/alts_credentials_corpus/c08bc84ab6a512b901bb730beb05c8394e4f1c5d
new file mode 100644
index 0000000..8d75368
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/c08bc84ab6a512b901bb730beb05c8394e4f1c5d
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/c244b635d94e6f5d6b344887434be3e001a04b41 b/test/core/security/corpus/alts_credentials_corpus/c244b635d94e6f5d6b344887434be3e001a04b41
new file mode 100644
index 0000000..92e73a2
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/c244b635d94e6f5d6b344887434be3e001a04b41
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/c281efe9620da999a637ff6e9b3279ec613fb992 b/test/core/security/corpus/alts_credentials_corpus/c281efe9620da999a637ff6e9b3279ec613fb992
new file mode 100644
index 0000000..c17a77e
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/c281efe9620da999a637ff6e9b3279ec613fb992
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/c30a212824ee71e215f475f453de17c65a200101 b/test/core/security/corpus/alts_credentials_corpus/c30a212824ee71e215f475f453de17c65a200101
new file mode 100644
index 0000000..86ac99e
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/c30a212824ee71e215f475f453de17c65a200101
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/c449427f35b7ecdf5641073629f7723df52c4cb0 b/test/core/security/corpus/alts_credentials_corpus/c449427f35b7ecdf5641073629f7723df52c4cb0
new file mode 100644
index 0000000..87d1a32
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/c449427f35b7ecdf5641073629f7723df52c4cb0
@@ -0,0 +1 @@
+ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕÒÒÒÒÒÒÒÒÒÒ-
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/c60240cd3b02eb71e2bf5ebd59afa3a5dc9b5e4d b/test/core/security/corpus/alts_credentials_corpus/c60240cd3b02eb71e2bf5ebd59afa3a5dc9b5e4d
new file mode 100644
index 0000000..f8804b8
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/c60240cd3b02eb71e2bf5ebd59afa3a5dc9b5e4d
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/c60cdf9c3fb9060838f445b3bc3852b6f81e1e4c b/test/core/security/corpus/alts_credentials_corpus/c60cdf9c3fb9060838f445b3bc3852b6f81e1e4c
new file mode 100644
index 0000000..327246f
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/c60cdf9c3fb9060838f445b3bc3852b6f81e1e4c
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/c72d0501bacadb45242c553ba292591302f12a6a b/test/core/security/corpus/alts_credentials_corpus/c72d0501bacadb45242c553ba292591302f12a6a
new file mode 100644
index 0000000..ca02baf
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/c72d0501bacadb45242c553ba292591302f12a6a
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/c739e7b5ad999edbdeffdab672dbc30deb3959a0 b/test/core/security/corpus/alts_credentials_corpus/c739e7b5ad999edbdeffdab672dbc30deb3959a0
new file mode 100644
index 0000000..d7f2d22
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/c739e7b5ad999edbdeffdab672dbc30deb3959a0
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/c7d73b12a7108d82f8dac6d8a6a34f838601aca6 b/test/core/security/corpus/alts_credentials_corpus/c7d73b12a7108d82f8dac6d8a6a34f838601aca6
new file mode 100644
index 0000000..b38437a
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/c7d73b12a7108d82f8dac6d8a6a34f838601aca6
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/ca781e1add632433293e847ae9e71649c217ee5f b/test/core/security/corpus/alts_credentials_corpus/ca781e1add632433293e847ae9e71649c217ee5f
new file mode 100644
index 0000000..5c79dd1
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/ca781e1add632433293e847ae9e71649c217ee5f
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/cc48e916f40e8d69c2d07cfda42c7d3b7fe3447a b/test/core/security/corpus/alts_credentials_corpus/cc48e916f40e8d69c2d07cfda42c7d3b7fe3447a
new file mode 100644
index 0000000..11ccb07
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/cc48e916f40e8d69c2d07cfda42c7d3b7fe3447a
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/cca1aff4c08ee4ccbcb6f80e1cd1480a0a093cfd b/test/core/security/corpus/alts_credentials_corpus/cca1aff4c08ee4ccbcb6f80e1cd1480a0a093cfd
new file mode 100644
index 0000000..b7bebbe
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/cca1aff4c08ee4ccbcb6f80e1cd1480a0a093cfd
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/cf6ae8bf1d08d25e235b7bee0839984bbc04edf6 b/test/core/security/corpus/alts_credentials_corpus/cf6ae8bf1d08d25e235b7bee0839984bbc04edf6
new file mode 100644
index 0000000..32eb656
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/cf6ae8bf1d08d25e235b7bee0839984bbc04edf6
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/cfc52fa086292c699efd7bf41d2fae3deb449536 b/test/core/security/corpus/alts_credentials_corpus/cfc52fa086292c699efd7bf41d2fae3deb449536
new file mode 100644
index 0000000..285e35d
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/cfc52fa086292c699efd7bf41d2fae3deb449536
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/cfe13ef3c6c713a059f231f0001ecec97e2a932d b/test/core/security/corpus/alts_credentials_corpus/cfe13ef3c6c713a059f231f0001ecec97e2a932d
new file mode 100644
index 0000000..1059f60
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/cfe13ef3c6c713a059f231f0001ecec97e2a932d
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/d14026ac6421bca7161024f4e735cb80a1068d01 b/test/core/security/corpus/alts_credentials_corpus/d14026ac6421bca7161024f4e735cb80a1068d01
new file mode 100644
index 0000000..68b7682
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/d14026ac6421bca7161024f4e735cb80a1068d01
@@ -0,0 +1,2 @@
+
+ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ+´úä¯õ
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/d2fb6e8f7867fc1e2ebe723da2b5246dc9cc6b14 b/test/core/security/corpus/alts_credentials_corpus/d2fb6e8f7867fc1e2ebe723da2b5246dc9cc6b14
new file mode 100644
index 0000000..9854260
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/d2fb6e8f7867fc1e2ebe723da2b5246dc9cc6b14
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/d4db7d51bdaa4781cf12c3b59914bad414d2a41e b/test/core/security/corpus/alts_credentials_corpus/d4db7d51bdaa4781cf12c3b59914bad414d2a41e
new file mode 100644
index 0000000..0979d45
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/d4db7d51bdaa4781cf12c3b59914bad414d2a41e
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/d533da0e7f8c1e39bb025b4d7a89613142a6f54e b/test/core/security/corpus/alts_credentials_corpus/d533da0e7f8c1e39bb025b4d7a89613142a6f54e
new file mode 100644
index 0000000..89ef0d2
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/d533da0e7f8c1e39bb025b4d7a89613142a6f54e
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/d5cf489d01a1b847a7aac5dddabff23fdc218e1e b/test/core/security/corpus/alts_credentials_corpus/d5cf489d01a1b847a7aac5dddabff23fdc218e1e
new file mode 100644
index 0000000..c544b27
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/d5cf489d01a1b847a7aac5dddabff23fdc218e1e
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/d686f8561a249c7c15c78f76a5fceb884286e070 b/test/core/security/corpus/alts_credentials_corpus/d686f8561a249c7c15c78f76a5fceb884286e070
new file mode 100644
index 0000000..b96c459
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/d686f8561a249c7c15c78f76a5fceb884286e070
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/d92424daad9d96a40e5ab177e3824c36ef51dc0f b/test/core/security/corpus/alts_credentials_corpus/d92424daad9d96a40e5ab177e3824c36ef51dc0f
new file mode 100644
index 0000000..509eb39
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/d92424daad9d96a40e5ab177e3824c36ef51dc0f
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/db242a11ed88b2b26af46770dd1927d9f35301fb b/test/core/security/corpus/alts_credentials_corpus/db242a11ed88b2b26af46770dd1927d9f35301fb
new file mode 100644
index 0000000..bd5d046
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/db242a11ed88b2b26af46770dd1927d9f35301fb
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/db32eb04db13d58f65f46d262608bd088987c063 b/test/core/security/corpus/alts_credentials_corpus/db32eb04db13d58f65f46d262608bd088987c063
new file mode 100644
index 0000000..5c526d8
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/db32eb04db13d58f65f46d262608bd088987c063
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/db39a953317951759e40734de6607a0b4457728e b/test/core/security/corpus/alts_credentials_corpus/db39a953317951759e40734de6607a0b4457728e
new file mode 100644
index 0000000..d794576
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/db39a953317951759e40734de6607a0b4457728e
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/dc5e8f3102456bed90d17303bc4cff1a7e076d5d b/test/core/security/corpus/alts_credentials_corpus/dc5e8f3102456bed90d17303bc4cff1a7e076d5d
new file mode 100644
index 0000000..53e1bbc
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/dc5e8f3102456bed90d17303bc4cff1a7e076d5d
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/dd9542bbed8e5dc58da2789edbfb9c38d578d3b4 b/test/core/security/corpus/alts_credentials_corpus/dd9542bbed8e5dc58da2789edbfb9c38d578d3b4
new file mode 100644
index 0000000..95fd950
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/dd9542bbed8e5dc58da2789edbfb9c38d578d3b4
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/de2ebb1ed324385de500a1a3308846239857c3c7 b/test/core/security/corpus/alts_credentials_corpus/de2ebb1ed324385de500a1a3308846239857c3c7
new file mode 100644
index 0000000..d0cee5f
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/de2ebb1ed324385de500a1a3308846239857c3c7
@@ -0,0 +1 @@
+ø+ø
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/de8ba9158254c1cd84b53df1e4cdf1757b1392f1 b/test/core/security/corpus/alts_credentials_corpus/de8ba9158254c1cd84b53df1e4cdf1757b1392f1
new file mode 100644
index 0000000..1cbbe5b
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/de8ba9158254c1cd84b53df1e4cdf1757b1392f1
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/e1dd260746f50024822a8b729b89545d26decfb8 b/test/core/security/corpus/alts_credentials_corpus/e1dd260746f50024822a8b729b89545d26decfb8
new file mode 100644
index 0000000..c44854e
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/e1dd260746f50024822a8b729b89545d26decfb8
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/e29add81b20dc570fdc885782689f6dccb1c5fad b/test/core/security/corpus/alts_credentials_corpus/e29add81b20dc570fdc885782689f6dccb1c5fad
new file mode 100644
index 0000000..5c50fe7
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/e29add81b20dc570fdc885782689f6dccb1c5fad
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/e2e99af62843cd3b29d50daeb118e58830784da9 b/test/core/security/corpus/alts_credentials_corpus/e2e99af62843cd3b29d50daeb118e58830784da9
new file mode 100644
index 0000000..04da131
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/e2e99af62843cd3b29d50daeb118e58830784da9
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/e46611c5daf99662e1576147c1623409752a1f39 b/test/core/security/corpus/alts_credentials_corpus/e46611c5daf99662e1576147c1623409752a1f39
new file mode 100644
index 0000000..0334d31
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/e46611c5daf99662e1576147c1623409752a1f39
@@ -0,0 +1 @@
+ä##
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/e5a1ba11af830e9d2db201c5164f75747a85fe9b b/test/core/security/corpus/alts_credentials_corpus/e5a1ba11af830e9d2db201c5164f75747a85fe9b
new file mode 100644
index 0000000..8e8b1e2
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/e5a1ba11af830e9d2db201c5164f75747a85fe9b
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/e6026ee0badf216b326443a5f708446b2f2e579f b/test/core/security/corpus/alts_credentials_corpus/e6026ee0badf216b326443a5f708446b2f2e579f
new file mode 100644
index 0000000..a99014f
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/e6026ee0badf216b326443a5f708446b2f2e579f
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/e6c7d2c0038fa1f03fc6590a726abc98f4c641f3 b/test/core/security/corpus/alts_credentials_corpus/e6c7d2c0038fa1f03fc6590a726abc98f4c641f3
new file mode 100644
index 0000000..8f5a9f5
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/e6c7d2c0038fa1f03fc6590a726abc98f4c641f3
@@ -0,0 +1 @@
+òi
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/eafdef6a630bed71bd0e4f3d4a16b5fa0c920651 b/test/core/security/corpus/alts_credentials_corpus/eafdef6a630bed71bd0e4f3d4a16b5fa0c920651
new file mode 100644
index 0000000..6fbe750
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/eafdef6a630bed71bd0e4f3d4a16b5fa0c920651
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/ece985b9b82e27281514d460709d7edf8203ded7 b/test/core/security/corpus/alts_credentials_corpus/ece985b9b82e27281514d460709d7edf8203ded7
new file mode 100644
index 0000000..c124302
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/ece985b9b82e27281514d460709d7edf8203ded7
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/edb8f4259f756c2c4bc731f05beaa36f992cf079 b/test/core/security/corpus/alts_credentials_corpus/edb8f4259f756c2c4bc731f05beaa36f992cf079
new file mode 100644
index 0000000..1cc08a4
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/edb8f4259f756c2c4bc731f05beaa36f992cf079
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/edce7778c2e1adb81dda3d057a6536759a7cb293 b/test/core/security/corpus/alts_credentials_corpus/edce7778c2e1adb81dda3d057a6536759a7cb293
new file mode 100644
index 0000000..39b52cf
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/edce7778c2e1adb81dda3d057a6536759a7cb293
@@ -0,0 +1 @@
++
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/ee4040c0dd406dd616c49ed2c37b40478dabfe0f b/test/core/security/corpus/alts_credentials_corpus/ee4040c0dd406dd616c49ed2c37b40478dabfe0f
new file mode 100644
index 0000000..48325e3
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/ee4040c0dd406dd616c49ed2c37b40478dabfe0f
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/ee69f2b380663d051a70f30fcfce9f79f5341e5a b/test/core/security/corpus/alts_credentials_corpus/ee69f2b380663d051a70f30fcfce9f79f5341e5a
new file mode 100644
index 0000000..7e0ad2a
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/ee69f2b380663d051a70f30fcfce9f79f5341e5a
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/efc6743e47274058771bb6eda1fefa017bde4a95 b/test/core/security/corpus/alts_credentials_corpus/efc6743e47274058771bb6eda1fefa017bde4a95
new file mode 100644
index 0000000..4418e8a
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/efc6743e47274058771bb6eda1fefa017bde4a95
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/f0038e54162000694d882b1acb80930c807b41d2 b/test/core/security/corpus/alts_credentials_corpus/f0038e54162000694d882b1acb80930c807b41d2
new file mode 100644
index 0000000..292a5e4
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/f0038e54162000694d882b1acb80930c807b41d2
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/f1deb9e388c877337dabe92f31b01e2a019a10f4 b/test/core/security/corpus/alts_credentials_corpus/f1deb9e388c877337dabe92f31b01e2a019a10f4
new file mode 100644
index 0000000..46464ee
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/f1deb9e388c877337dabe92f31b01e2a019a10f4
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/f3a09373e4d3c7310d372089e6deb15d6b22c198 b/test/core/security/corpus/alts_credentials_corpus/f3a09373e4d3c7310d372089e6deb15d6b22c198
new file mode 100644
index 0000000..a974996
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/f3a09373e4d3c7310d372089e6deb15d6b22c198
@@ -0,0 +1 @@
+üÒûþ
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/f3db7ef6495fa1ac5bb4db293fb38dd59122bb7c b/test/core/security/corpus/alts_credentials_corpus/f3db7ef6495fa1ac5bb4db293fb38dd59122bb7c
new file mode 100644
index 0000000..8afc32b
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/f3db7ef6495fa1ac5bb4db293fb38dd59122bb7c
@@ -0,0 +1,2 @@
+[ÿÿ[ÿÿÿ
+¡
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/f434bb4ceecc573e085d4c3ef453ef01e93d9c89 b/test/core/security/corpus/alts_credentials_corpus/f434bb4ceecc573e085d4c3ef453ef01e93d9c89
new file mode 100644
index 0000000..2b66a00
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/f434bb4ceecc573e085d4c3ef453ef01e93d9c89
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/f55bceaad42ddf9d2b37fdfca68255d29a696109 b/test/core/security/corpus/alts_credentials_corpus/f55bceaad42ddf9d2b37fdfca68255d29a696109
new file mode 100644
index 0000000..a8eef8f
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/f55bceaad42ddf9d2b37fdfca68255d29a696109
@@ -0,0 +1 @@
+òÒ
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/f62ca5321428a5d23f3c804fb51eb4e65bc58716 b/test/core/security/corpus/alts_credentials_corpus/f62ca5321428a5d23f3c804fb51eb4e65bc58716
new file mode 100644
index 0000000..0d80f7b
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/f62ca5321428a5d23f3c804fb51eb4e65bc58716
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/f7c6a558b8d0af64db2b139371a7af7068b01b92 b/test/core/security/corpus/alts_credentials_corpus/f7c6a558b8d0af64db2b139371a7af7068b01b92
new file mode 100644
index 0000000..d46ea45
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/f7c6a558b8d0af64db2b139371a7af7068b01b92
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/faa1781e1444bba5b8c677bc5e2a38d023a1ec65 b/test/core/security/corpus/alts_credentials_corpus/faa1781e1444bba5b8c677bc5e2a38d023a1ec65
new file mode 100644
index 0000000..013d565
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/faa1781e1444bba5b8c677bc5e2a38d023a1ec65
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/fceba33ada1dda05fccedfefd331c9a201f1a2e5 b/test/core/security/corpus/alts_credentials_corpus/fceba33ada1dda05fccedfefd331c9a201f1a2e5
new file mode 100644
index 0000000..f3db26d
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/fceba33ada1dda05fccedfefd331c9a201f1a2e5
@@ -0,0 +1 @@
+¿
\ No newline at end of file
diff --git a/test/core/security/corpus/alts_credentials_corpus/fd668bef6fdaf7f3ffd58d8c60ce550476652e60 b/test/core/security/corpus/alts_credentials_corpus/fd668bef6fdaf7f3ffd58d8c60ce550476652e60
new file mode 100644
index 0000000..dcefd99
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/fd668bef6fdaf7f3ffd58d8c60ce550476652e60
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/fdf06b928e37e7c4ae59a568b5723ad98bbed6e5 b/test/core/security/corpus/alts_credentials_corpus/fdf06b928e37e7c4ae59a568b5723ad98bbed6e5
new file mode 100644
index 0000000..fe28d69
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/fdf06b928e37e7c4ae59a568b5723ad98bbed6e5
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/fe2fc5d499aeb2762387ef2e3ce939280813dec0 b/test/core/security/corpus/alts_credentials_corpus/fe2fc5d499aeb2762387ef2e3ce939280813dec0
new file mode 100644
index 0000000..cb035e7
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/fe2fc5d499aeb2762387ef2e3ce939280813dec0
Binary files differ
diff --git a/test/core/security/corpus/alts_credentials_corpus/ff548d368b090409a138e5cc4afc7f43b4a3fbbd b/test/core/security/corpus/alts_credentials_corpus/ff548d368b090409a138e5cc4afc7f43b4a3fbbd
new file mode 100644
index 0000000..caadbc0
--- /dev/null
+++ b/test/core/security/corpus/alts_credentials_corpus/ff548d368b090409a138e5cc4afc7f43b4a3fbbd
Binary files differ
diff --git a/test/core/security/credentials_test.cc b/test/core/security/credentials_test.cc
index ce92e21..2b90939 100644
--- a/test/core/security/credentials_test.cc
+++ b/test/core/security/credentials_test.cc
@@ -867,6 +867,7 @@
static void test_google_default_creds_auth_key(void) {
grpc_core::ExecCtx exec_ctx;
grpc_service_account_jwt_access_credentials* jwt;
+ grpc_google_default_channel_credentials* default_creds;
grpc_composite_channel_credentials* creds;
char* json_key = test_json_key_str();
grpc_flush_cached_google_default_credentials();
@@ -875,7 +876,9 @@
gpr_free(json_key);
creds = reinterpret_cast<grpc_composite_channel_credentials*>(
grpc_google_default_credentials_create());
- GPR_ASSERT(creds != nullptr);
+ default_creds = reinterpret_cast<grpc_google_default_channel_credentials*>(
+ creds->inner_creds);
+ GPR_ASSERT(default_creds->ssl_creds != nullptr);
jwt = reinterpret_cast<grpc_service_account_jwt_access_credentials*>(
creds->call_creds);
GPR_ASSERT(
@@ -889,13 +892,16 @@
static void test_google_default_creds_refresh_token(void) {
grpc_core::ExecCtx exec_ctx;
grpc_google_refresh_token_credentials* refresh;
+ grpc_google_default_channel_credentials* default_creds;
grpc_composite_channel_credentials* creds;
grpc_flush_cached_google_default_credentials();
set_google_default_creds_env_var_with_file_contents(
"refresh_token_google_default_creds", test_refresh_token_str);
creds = reinterpret_cast<grpc_composite_channel_credentials*>(
grpc_google_default_credentials_create());
- GPR_ASSERT(creds != nullptr);
+ default_creds = reinterpret_cast<grpc_google_default_channel_credentials*>(
+ creds->inner_creds);
+ GPR_ASSERT(default_creds->ssl_creds != nullptr);
refresh = reinterpret_cast<grpc_google_refresh_token_credentials*>(
creds->call_creds);
GPR_ASSERT(strcmp(refresh->refresh_token.client_id,
diff --git a/test/core/security/grpc_alts_credentials_options_test.cc b/test/core/security/grpc_alts_credentials_options_test.cc
index 1217065..623db48 100644
--- a/test/core/security/grpc_alts_credentials_options_test.cc
+++ b/test/core/security/grpc_alts_credentials_options_test.cc
@@ -30,39 +30,22 @@
const size_t kTargetServiceAccountNum = 2;
-static void test_add_target_service_account_failure() {
- /* Initialization. */
- grpc_alts_credentials_options* options =
- grpc_alts_credentials_client_options_create();
- auto client_options =
- reinterpret_cast<grpc_alts_credentials_client_options*>(options);
-
- /* Test. */
- GPR_ASSERT(!grpc_alts_credentials_client_options_add_target_service_account(
- client_options, nullptr));
- GPR_ASSERT(!grpc_alts_credentials_client_options_add_target_service_account(
- nullptr, ALTS_CLIENT_OPTIONS_TEST_TARGET_SERVICE_ACCOUNT_1));
-
- /* Cleanup. */
- grpc_alts_credentials_options_destroy(options);
-}
-
static void test_copy_client_options_failure() {
/* Initialization. */
grpc_alts_credentials_options* options =
grpc_alts_credentials_client_options_create();
-
/* Test. */
GPR_ASSERT(grpc_alts_credentials_options_copy(nullptr) == nullptr);
-
/* Cleanup. */
grpc_alts_credentials_options_destroy(options);
}
static size_t get_target_service_account_num(
- grpc_alts_credentials_client_options* options) {
+ grpc_alts_credentials_options* options) {
+ auto client_options =
+ reinterpret_cast<grpc_alts_credentials_client_options*>(options);
size_t num = 0;
- target_service_account* node = options->target_account_list_head;
+ target_service_account* node = client_options->target_account_list_head;
while (node != nullptr) {
num++;
node = node->next;
@@ -74,36 +57,31 @@
/* Initialization. */
grpc_alts_credentials_options* options =
grpc_alts_credentials_client_options_create();
- auto client_options =
- reinterpret_cast<grpc_alts_credentials_client_options*>(options);
-
/* Set client options fields. */
grpc_alts_credentials_client_options_add_target_service_account(
- client_options, ALTS_CLIENT_OPTIONS_TEST_TARGET_SERVICE_ACCOUNT_1);
+ options, ALTS_CLIENT_OPTIONS_TEST_TARGET_SERVICE_ACCOUNT_1);
grpc_alts_credentials_client_options_add_target_service_account(
- client_options, ALTS_CLIENT_OPTIONS_TEST_TARGET_SERVICE_ACCOUNT_2);
-
+ options, ALTS_CLIENT_OPTIONS_TEST_TARGET_SERVICE_ACCOUNT_2);
/* Validate client option fields. */
- GPR_ASSERT(get_target_service_account_num(client_options) ==
+ GPR_ASSERT(get_target_service_account_num(options) ==
kTargetServiceAccountNum);
+ auto client_options =
+ reinterpret_cast<grpc_alts_credentials_client_options*>(options);
GPR_ASSERT(strcmp(client_options->target_account_list_head->data,
ALTS_CLIENT_OPTIONS_TEST_TARGET_SERVICE_ACCOUNT_2) == 0);
GPR_ASSERT(strcmp(client_options->target_account_list_head->next->data,
ALTS_CLIENT_OPTIONS_TEST_TARGET_SERVICE_ACCOUNT_1) == 0);
-
/* Perform a copy operation and validate its correctness. */
grpc_alts_credentials_options* new_options =
grpc_alts_credentials_options_copy(options);
+ GPR_ASSERT(get_target_service_account_num(new_options) ==
+ kTargetServiceAccountNum);
auto new_client_options =
reinterpret_cast<grpc_alts_credentials_client_options*>(new_options);
-
- GPR_ASSERT(get_target_service_account_num(new_client_options) ==
- kTargetServiceAccountNum);
GPR_ASSERT(strcmp(new_client_options->target_account_list_head->data,
ALTS_CLIENT_OPTIONS_TEST_TARGET_SERVICE_ACCOUNT_2) == 0);
GPR_ASSERT(strcmp(new_client_options->target_account_list_head->next->data,
ALTS_CLIENT_OPTIONS_TEST_TARGET_SERVICE_ACCOUNT_1) == 0);
-
/* Cleanup.*/
grpc_alts_credentials_options_destroy(options);
grpc_alts_credentials_options_destroy(new_options);
@@ -111,7 +89,6 @@
int main(int argc, char** argv) {
/* Test. */
- test_add_target_service_account_failure();
test_copy_client_options_failure();
test_client_options_api_success();
return 0;
diff --git a/test/core/security/security_connector_test.cc b/test/core/security/security_connector_test.cc
index f03f4cc..e4c3ace 100644
--- a/test/core/security/security_connector_test.cc
+++ b/test/core/security/security_connector_test.cc
@@ -87,15 +87,15 @@
GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_X509_CERTIFICATE_TYPE,
&peer.properties[0]) == TSI_OK);
- ctx = tsi_ssl_peer_to_auth_context(&peer);
+ ctx = grpc_ssl_peer_to_auth_context(&peer);
GPR_ASSERT(ctx != nullptr);
GPR_ASSERT(!grpc_auth_context_peer_is_authenticated(ctx));
GPR_ASSERT(check_transport_security_type(ctx));
- rpeer = tsi_shallow_peer_from_ssl_auth_context(ctx);
+ rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx);
GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer));
- tsi_shallow_peer_destruct(&rpeer);
+ grpc_shallow_peer_destruct(&rpeer);
tsi_peer_destruct(&peer);
GRPC_AUTH_CONTEXT_UNREF(ctx, "test");
}
@@ -187,7 +187,7 @@
GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
TSI_X509_PEM_CERT_PROPERTY, expected_pem_cert,
&peer.properties[2]) == TSI_OK);
- ctx = tsi_ssl_peer_to_auth_context(&peer);
+ ctx = grpc_ssl_peer_to_auth_context(&peer);
GPR_ASSERT(ctx != nullptr);
GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx));
GPR_ASSERT(check_identity(ctx, GRPC_X509_CN_PROPERTY_NAME, &expected_cn, 1));
@@ -195,10 +195,10 @@
GPR_ASSERT(check_x509_cn(ctx, expected_cn));
GPR_ASSERT(check_x509_pem_cert(ctx, expected_pem_cert));
- rpeer = tsi_shallow_peer_from_ssl_auth_context(ctx);
+ rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx);
GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer));
- tsi_shallow_peer_destruct(&rpeer);
+ grpc_shallow_peer_destruct(&rpeer);
tsi_peer_destruct(&peer);
GRPC_AUTH_CONTEXT_UNREF(ctx, "test");
}
@@ -223,7 +223,7 @@
GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
TSI_X509_PEM_CERT_PROPERTY, expected_pem_cert,
&peer.properties[3]) == TSI_OK);
- ctx = tsi_ssl_peer_to_auth_context(&peer);
+ ctx = grpc_ssl_peer_to_auth_context(&peer);
GPR_ASSERT(ctx != nullptr);
GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx));
GPR_ASSERT(
@@ -232,10 +232,10 @@
GPR_ASSERT(check_x509_cn(ctx, expected_cn));
GPR_ASSERT(check_x509_pem_cert(ctx, expected_pem_cert));
- rpeer = tsi_shallow_peer_from_ssl_auth_context(ctx);
+ rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx);
GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer));
- tsi_shallow_peer_destruct(&rpeer);
+ grpc_shallow_peer_destruct(&rpeer);
tsi_peer_destruct(&peer);
GRPC_AUTH_CONTEXT_UNREF(ctx, "test");
}
@@ -264,7 +264,7 @@
TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY,
expected_sans[i], &peer.properties[3 + i]) == TSI_OK);
}
- ctx = tsi_ssl_peer_to_auth_context(&peer);
+ ctx = grpc_ssl_peer_to_auth_context(&peer);
GPR_ASSERT(ctx != nullptr);
GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx));
GPR_ASSERT(check_identity(ctx, GRPC_X509_SAN_PROPERTY_NAME, expected_sans,
@@ -273,10 +273,10 @@
GPR_ASSERT(check_x509_cn(ctx, expected_cn));
GPR_ASSERT(check_x509_pem_cert(ctx, expected_pem_cert));
- rpeer = tsi_shallow_peer_from_ssl_auth_context(ctx);
+ rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx);
GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer));
- tsi_shallow_peer_destruct(&rpeer);
+ grpc_shallow_peer_destruct(&rpeer);
tsi_peer_destruct(&peer);
GRPC_AUTH_CONTEXT_UNREF(ctx, "test");
}
@@ -310,7 +310,7 @@
TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY,
expected_sans[i], &peer.properties[5 + i]) == TSI_OK);
}
- ctx = tsi_ssl_peer_to_auth_context(&peer);
+ ctx = grpc_ssl_peer_to_auth_context(&peer);
GPR_ASSERT(ctx != nullptr);
GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx));
GPR_ASSERT(check_identity(ctx, GRPC_X509_SAN_PROPERTY_NAME, expected_sans,
@@ -319,10 +319,10 @@
GPR_ASSERT(check_x509_cn(ctx, expected_cn));
GPR_ASSERT(check_x509_pem_cert(ctx, expected_pem_cert));
- rpeer = tsi_shallow_peer_from_ssl_auth_context(ctx);
+ rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx);
GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer));
- tsi_shallow_peer_destruct(&rpeer);
+ grpc_shallow_peer_destruct(&rpeer);
tsi_peer_destruct(&peer);
GRPC_AUTH_CONTEXT_UNREF(ctx, "test");
}
@@ -340,6 +340,26 @@
return GRPC_SSL_ROOTS_OVERRIDE_FAIL_PERMANENTLY;
}
+static void test_ipv6_address_san(void) {
+ const char* addresses[] = {
+ "2001:db8::1", "fe80::abcd:ef65:4321%em0", "fd11:feed:beef:0:cafe::4",
+ "128.10.0.1:8888", "[2001:db8::1]:8080", "[2001:db8::1%em1]:8080",
+ };
+ const char* san_ips[] = {
+ "2001:db8::1", "fe80::abcd:ef65:4321", "fd11:feed:beef:0:cafe::4",
+ "128.10.0.1", "2001:db8::1", "2001:db8::1",
+ };
+ tsi_peer peer;
+ GPR_ASSERT(tsi_construct_peer(1, &peer) == TSI_OK);
+ for (size_t i = 0; i < GPR_ARRAY_SIZE(addresses); i++) {
+ GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
+ TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, san_ips[i],
+ &peer.properties[0]) == TSI_OK);
+ GPR_ASSERT(grpc_ssl_host_matches_name(&peer, addresses[i]));
+ tsi_peer_property_destruct(&peer.properties[0]);
+ }
+ tsi_peer_destruct(&peer);
+}
namespace grpc_core {
namespace {
@@ -416,6 +436,7 @@
test_cn_and_one_san_ssl_peer_to_auth_context();
test_cn_and_multiple_sans_ssl_peer_to_auth_context();
test_cn_and_multiple_sans_and_others_ssl_peer_to_auth_context();
+ test_ipv6_address_san();
test_default_ssl_roots();
grpc_shutdown();
diff --git a/test/core/surface/BUILD b/test/core/surface/BUILD
index e848dde..77df1cc 100644
--- a/test/core/surface/BUILD
+++ b/test/core/surface/BUILD
@@ -91,18 +91,6 @@
)
grpc_cc_test(
- name = "grpc_invalid_channel_args_test",
- srcs = ["invalid_channel_args_test.cc"],
- language = "C++",
- deps = [
- "//:gpr",
- "//:grpc",
- "//test/core/util:gpr_test_util",
- "//test/core/util:grpc_test_util",
- ],
-)
-
-grpc_cc_test(
name = "lame_client_test",
srcs = ["lame_client_test.cc"],
language = "C++",
diff --git a/test/core/surface/invalid_channel_args_test.cc b/test/core/surface/invalid_channel_args_test.cc
deleted file mode 100644
index 7c5f1f0..0000000
--- a/test/core/surface/invalid_channel_args_test.cc
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- *
- * 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.
- *
- */
-
-#include <grpc/grpc.h>
-#include <string.h>
-
-#include <grpc/support/alloc.h>
-#include <grpc/support/log.h>
-#include <grpc/support/string_util.h>
-#include "test/core/util/test_config.h"
-
-static char* g_last_log_error_message = nullptr;
-static const char* g_file_name = "channel.cc";
-
-static int ends_with(const char* src, const char* suffix) {
- size_t src_len = strlen(src);
- size_t suffix_len = strlen(suffix);
- if (src_len < suffix_len) {
- return 0;
- }
- return strcmp(src + src_len - suffix_len, suffix) == 0;
-}
-
-static void log_error_sink(gpr_log_func_args* args) {
- if (args->severity == GPR_LOG_SEVERITY_ERROR &&
- ends_with(args->file, g_file_name)) {
- g_last_log_error_message = gpr_strdup(args->message);
- }
-}
-
-static void verify_last_error(const char* message) {
- if (message == nullptr) {
- GPR_ASSERT(g_last_log_error_message == nullptr);
- return;
- }
- GPR_ASSERT(strcmp(message, g_last_log_error_message) == 0);
- gpr_free(g_last_log_error_message);
- g_last_log_error_message = nullptr;
-}
-
-static char* compose_error_string(const char* key, const char* message) {
- char* ret;
- gpr_asprintf(&ret, "%s%s", key, message);
- return ret;
-}
-
-static void one_test(grpc_channel_args* args, char* expected_error_message) {
- grpc_channel* chan =
- grpc_insecure_channel_create("nonexistant:54321", args, nullptr);
- verify_last_error(expected_error_message);
- gpr_free(expected_error_message);
- grpc_channel_destroy(chan);
-}
-
-static void test_no_error_message(void) { one_test(nullptr, nullptr); }
-
-static void test_default_authority_type(void) {
- grpc_arg client_arg;
- grpc_channel_args client_args;
- char* expected_error_message;
-
- client_arg.type = GRPC_ARG_INTEGER;
- client_arg.key = const_cast<char*>(GRPC_ARG_DEFAULT_AUTHORITY);
- client_arg.value.integer = 0;
-
- client_args.num_args = 1;
- client_args.args = &client_arg;
- expected_error_message = compose_error_string(
- GRPC_ARG_DEFAULT_AUTHORITY, " ignored: it must be a string");
- one_test(&client_args, expected_error_message);
-}
-
-static void test_ssl_name_override_type(void) {
- grpc_arg client_arg;
- grpc_channel_args client_args;
- char* expected_error_message;
-
- client_arg.type = GRPC_ARG_INTEGER;
- client_arg.key = const_cast<char*>(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG);
- client_arg.value.integer = 0;
-
- client_args.num_args = 1;
- client_args.args = &client_arg;
- expected_error_message = compose_error_string(
- GRPC_SSL_TARGET_NAME_OVERRIDE_ARG, " ignored: it must be a string");
- one_test(&client_args, expected_error_message);
-}
-
-static void test_ssl_name_override_failed(void) {
- grpc_arg client_arg[2];
- grpc_channel_args client_args;
- char* expected_error_message;
-
- client_arg[0].type = GRPC_ARG_STRING;
- client_arg[0].key = const_cast<char*>(GRPC_ARG_DEFAULT_AUTHORITY);
- client_arg[0].value.string = const_cast<char*>("default");
- client_arg[1].type = GRPC_ARG_STRING;
- client_arg[1].key = const_cast<char*>(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG);
- client_arg[1].value.string = const_cast<char*>("ssl");
-
- client_args.num_args = 2;
- client_args.args = client_arg;
- expected_error_message =
- compose_error_string(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG,
- " ignored: default host already set some other way");
- one_test(&client_args, expected_error_message);
-}
-
-int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
- grpc_init();
- gpr_set_log_function(log_error_sink);
-
- test_no_error_message();
- test_default_authority_type();
- test_ssl_name_override_type();
- test_ssl_name_override_failed();
-
- grpc_shutdown();
-
- 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 866bee5..52a1b03 100644
--- a/test/core/surface/public_headers_must_be_c89.c
+++ b/test/core/surface/public_headers_must_be_c89.c
@@ -173,6 +173,12 @@
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_alts_credentials_client_options_create);
+ printf("%lx", (unsigned long) grpc_alts_credentials_server_options_create);
+ printf("%lx", (unsigned long) grpc_alts_credentials_client_options_add_target_service_account);
+ printf("%lx", (unsigned long) grpc_alts_credentials_options_destroy);
+ printf("%lx", (unsigned long) grpc_alts_credentials_create);
+ printf("%lx", (unsigned long) grpc_alts_server_credentials_create);
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);
@@ -243,6 +249,7 @@
printf("%lx", (unsigned long) gpr_cpu_current_cpu);
printf("%lx", (unsigned long) gpr_log_severity_string);
printf("%lx", (unsigned long) gpr_log);
+ printf("%lx", (unsigned long) gpr_should_log);
printf("%lx", (unsigned long) gpr_log_message);
printf("%lx", (unsigned long) gpr_set_log_verbosity);
printf("%lx", (unsigned long) gpr_log_verbosity_init);
diff --git a/test/core/surface/server_chttp2_test.cc b/test/core/surface/server_chttp2_test.cc
index f0412d0..fd8ab9c 100644
--- a/test/core/surface/server_chttp2_test.cc
+++ b/test/core/surface/server_chttp2_test.cc
@@ -37,6 +37,8 @@
grpc_server_destroy(server);
}
+// GRPC_ARG_ALLOW_REUSEPORT isn't supported for custom servers
+#ifndef GRPC_UV
void test_add_same_port_twice() {
grpc_arg a;
a.type = GRPC_ARG_INTEGER;
@@ -62,12 +64,15 @@
grpc_server_destroy(server);
grpc_completion_queue_destroy(cq);
}
+#endif
int main(int argc, char** argv) {
grpc_test_init(argc, argv);
grpc_init();
test_unparsable_target();
+#ifndef GRPC_UV
test_add_same_port_twice();
+#endif
grpc_shutdown();
return 0;
}
diff --git a/test/core/surface/server_test.cc b/test/core/surface/server_test.cc
index 3b08efb..b4eabd8 100644
--- a/test/core/surface/server_test.cc
+++ b/test/core/surface/server_test.cc
@@ -69,6 +69,8 @@
grpc_server_destroy(server);
}
+// GRPC_ARG_ALLOW_REUSEPORT isn't supported for custom servers
+#ifndef GRPC_UV
void test_bind_server_twice(void) {
grpc_arg a;
a.type = GRPC_ARG_INTEGER;
@@ -100,6 +102,7 @@
grpc_completion_queue_destroy(cq);
gpr_free(addr);
}
+#endif
void test_bind_server_to_addr(const char* host, bool secure) {
int port = grpc_pick_unused_port_or_die();
@@ -149,7 +152,9 @@
grpc_init();
test_register_method_fail();
test_request_call_on_no_server_cq();
+#ifndef GRPC_UV
test_bind_server_twice();
+#endif
static const char* addrs[] = {
"::1", "127.0.0.1", "::ffff:127.0.0.1", "localhost", "0.0.0.0", "::",
diff --git a/test/core/tsi/alts/crypt/BUILD b/test/core/tsi/alts/crypt/BUILD
index b2fcb65..cf9dbca 100644
--- a/test/core/tsi/alts/crypt/BUILD
+++ b/test/core/tsi/alts/crypt/BUILD
@@ -16,7 +16,7 @@
licenses(["notice"]) # Apache v2
-grpc_package(name = "crypt", visibility = "public")
+grpc_package(name = "test/core/tsi/alts/crypt", visibility = "public")
grpc_cc_test(
name = "alts_crypt_test",
diff --git a/test/core/tsi/alts/fake_handshaker/BUILD b/test/core/tsi/alts/fake_handshaker/BUILD
new file mode 100644
index 0000000..a09a046
--- /dev/null
+++ b/test/core/tsi/alts/fake_handshaker/BUILD
@@ -0,0 +1,57 @@
+# Copyright 2018 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.
+
+licenses(["notice"]) # Apache v2
+
+load("//bazel:grpc_build_system.bzl", "grpc_proto_library", "grpc_cc_library", "grpc_cc_binary", "grpc_package")
+
+grpc_package(name = "test/core/tsi/alts/fake_handshaker", visibility = "public")
+
+grpc_proto_library(
+ name = "transport_security_common_proto",
+ srcs = ["transport_security_common.proto"],
+ has_services = False,
+)
+
+grpc_proto_library(
+ name = "handshaker_proto",
+ srcs = ["handshaker.proto"],
+ has_services = True,
+ deps = [
+ "transport_security_common_proto",
+ ],
+)
+
+grpc_cc_library(
+ name = "fake_handshaker_lib",
+ testonly = True,
+ srcs = ["fake_handshaker_server.cc"],
+ language = "C++",
+ deps = [
+ "handshaker_proto",
+ "transport_security_common_proto",
+ "//:grpc++",
+ "//test/cpp/util:test_config",
+ ],
+)
+
+grpc_cc_binary(
+ name = "fake_handshaker_server",
+ testonly = True,
+ srcs = ["fake_handshaker_server.cc"],
+ language = "C++",
+ deps = [
+ "fake_handshaker_lib",
+ ],
+)
diff --git a/test/core/tsi/alts/fake_handshaker/fake_handshaker_server.cc b/test/core/tsi/alts/fake_handshaker/fake_handshaker_server.cc
new file mode 100644
index 0000000..f6a4791
--- /dev/null
+++ b/test/core/tsi/alts/fake_handshaker/fake_handshaker_server.cc
@@ -0,0 +1,268 @@
+/*
+ *
+ * Copyright 2018 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.
+ *
+ */
+
+#include <memory>
+#include <sstream>
+#include <string>
+
+#include <gflags/gflags.h>
+#include <grpc/grpc.h>
+#include <grpc/support/log.h>
+#include <grpcpp/impl/codegen/async_stream.h>
+#include <grpcpp/security/server_credentials.h>
+#include <grpcpp/server.h>
+#include <grpcpp/server_builder.h>
+#include <grpcpp/server_context.h>
+
+#include "test/core/tsi/alts/fake_handshaker/handshaker.grpc.pb.h"
+#include "test/core/tsi/alts/fake_handshaker/handshaker.pb.h"
+#include "test/core/tsi/alts/fake_handshaker/transport_security_common.pb.h"
+#include "test/cpp/util/test_config.h"
+
+DEFINE_int32(handshaker_port, 55056,
+ "TCP port on which the fake handshaker server listens to.");
+
+// Fake handshake messages.
+constexpr char kClientInitFrame[] = "ClientInit";
+constexpr char kServerFrame[] = "ServerInitAndFinished";
+constexpr char kClientFinishFrame[] = "ClientFinished";
+// Error messages.
+constexpr char kInvalidFrameError[] = "Invalid input frame.";
+constexpr char kWrongStateError[] = "Wrong handshake state.";
+
+namespace grpc {
+namespace gcp {
+
+// FakeHandshakeService implements a fake handshaker service using a fake key
+// exchange protocol. The fake key exchange protocol is a 3-message protocol:
+// - Client first sends ClientInit message to Server.
+// - Server then sends ServerInitAndFinished message back to Client.
+// - Client finally sends ClientFinished message to Server.
+// This fake handshaker service is intended for ALTS integration testing without
+// relying on real ALTS handshaker service inside GCE.
+// It is thread-safe.
+class FakeHandshakerService : public HandshakerService::Service {
+ public:
+ Status DoHandshake(
+ ServerContext* server_context,
+ ServerReaderWriter<HandshakerResp, HandshakerReq>* stream) override {
+ Status status;
+ HandshakerContext context;
+ HandshakerReq request;
+ HandshakerResp response;
+ gpr_log(GPR_DEBUG, "Start a new handshake.");
+ while (stream->Read(&request)) {
+ status = ProcessRequest(&context, request, &response);
+ if (!status.ok()) return WriteErrorResponse(stream, status);
+ stream->Write(response);
+ if (context.state == COMPLETED) return Status::OK;
+ request.Clear();
+ }
+ return Status::OK;
+ }
+
+ private:
+ // HandshakeState is used by fake handshaker server to keep track of client's
+ // handshake status. In the beginning of a handshake, the state is INITIAL.
+ // If start_client or start_server request is called, the state becomes at
+ // least STARTED. When the handshaker server produces the first fame, the
+ // state becomes SENT. After the handshaker server processes the final frame
+ // from the peer, the state becomes COMPLETED.
+ enum HandshakeState { INITIAL, STARTED, SENT, COMPLETED };
+
+ struct HandshakerContext {
+ bool is_client = true;
+ HandshakeState state = INITIAL;
+ };
+
+ Status ProcessRequest(HandshakerContext* context,
+ const HandshakerReq& request,
+ HandshakerResp* response) {
+ GPR_ASSERT(context != nullptr && response != nullptr);
+ response->Clear();
+ if (request.has_client_start()) {
+ gpr_log(GPR_DEBUG, "Process client start request.");
+ return ProcessClientStart(context, request.client_start(), response);
+ } else if (request.has_server_start()) {
+ gpr_log(GPR_DEBUG, "Process server start request.");
+ return ProcessServerStart(context, request.server_start(), response);
+ } else if (request.has_next()) {
+ gpr_log(GPR_DEBUG, "Process next request.");
+ return ProcessNext(context, request.next(), response);
+ }
+ return Status(StatusCode::INVALID_ARGUMENT, "Request is empty.");
+ }
+
+ Status ProcessClientStart(HandshakerContext* context,
+ const StartClientHandshakeReq& request,
+ HandshakerResp* response) {
+ GPR_ASSERT(context != nullptr && response != nullptr);
+ // Checks request.
+ if (context->state != INITIAL) {
+ return Status(StatusCode::FAILED_PRECONDITION, kWrongStateError);
+ }
+ if (request.application_protocols_size() == 0) {
+ return Status(StatusCode::INVALID_ARGUMENT,
+ "At least one application protocol needed.");
+ }
+ if (request.record_protocols_size() == 0) {
+ return Status(StatusCode::INVALID_ARGUMENT,
+ "At least one record protocol needed.");
+ }
+ // Sets response.
+ response->set_out_frames(kClientInitFrame);
+ response->set_bytes_consumed(0);
+ response->mutable_status()->set_code(StatusCode::OK);
+ // Updates handshaker context.
+ context->is_client = true;
+ context->state = SENT;
+ return Status::OK;
+ }
+
+ Status ProcessServerStart(HandshakerContext* context,
+ const StartServerHandshakeReq& request,
+ HandshakerResp* response) {
+ GPR_ASSERT(context != nullptr && response != nullptr);
+ // Checks request.
+ if (context->state != INITIAL) {
+ return Status(StatusCode::FAILED_PRECONDITION, kWrongStateError);
+ }
+ if (request.application_protocols_size() == 0) {
+ return Status(StatusCode::INVALID_ARGUMENT,
+ "At least one application protocol needed.");
+ }
+ if (request.handshake_parameters().empty()) {
+ return Status(StatusCode::INVALID_ARGUMENT,
+ "At least one set of handshake parameters needed.");
+ }
+ // Sets response.
+ if (request.in_bytes().empty()) {
+ // start_server request does not have in_bytes.
+ response->set_bytes_consumed(0);
+ context->state = STARTED;
+ } else {
+ // start_server request has in_bytes.
+ if (request.in_bytes() == kClientInitFrame) {
+ response->set_out_frames(kServerFrame);
+ response->set_bytes_consumed(strlen(kClientInitFrame));
+ context->state = SENT;
+ } else {
+ return Status(StatusCode::UNKNOWN, kInvalidFrameError);
+ }
+ }
+ response->mutable_status()->set_code(StatusCode::OK);
+ context->is_client = false;
+ return Status::OK;
+ }
+
+ Status ProcessNext(HandshakerContext* context,
+ const NextHandshakeMessageReq& request,
+ HandshakerResp* response) {
+ GPR_ASSERT(context != nullptr && response != nullptr);
+ if (context->is_client) {
+ // Processes next request on client side.
+ if (context->state != SENT) {
+ return Status(StatusCode::FAILED_PRECONDITION, kWrongStateError);
+ }
+ if (request.in_bytes() != kServerFrame) {
+ return Status(StatusCode::UNKNOWN, kInvalidFrameError);
+ }
+ response->set_out_frames(kClientFinishFrame);
+ response->set_bytes_consumed(strlen(kServerFrame));
+ context->state = COMPLETED;
+ } else {
+ // Processes next request on server side.
+ HandshakeState current_state = context->state;
+ if (current_state == STARTED) {
+ if (request.in_bytes() != kClientInitFrame) {
+ return Status(StatusCode::UNKNOWN, kInvalidFrameError);
+ }
+ response->set_out_frames(kServerFrame);
+ response->set_bytes_consumed(strlen(kClientInitFrame));
+ context->state = SENT;
+ } else if (current_state == SENT) {
+ // Client finish frame may be sent along with the first payload from the
+ // client, handshaker only consumes the client finish frame.
+ if (request.in_bytes().substr(0, strlen(kClientFinishFrame)) !=
+ kClientFinishFrame) {
+ return Status(StatusCode::UNKNOWN, kInvalidFrameError);
+ }
+ response->set_bytes_consumed(strlen(kClientFinishFrame));
+ context->state = COMPLETED;
+ } else {
+ return Status(StatusCode::FAILED_PRECONDITION, kWrongStateError);
+ }
+ }
+ // At this point, processing next request succeeded.
+ response->mutable_status()->set_code(StatusCode::OK);
+ if (context->state == COMPLETED) {
+ *response->mutable_result() = GetHandshakerResult();
+ }
+ return Status::OK;
+ }
+
+ Status WriteErrorResponse(
+ ServerReaderWriter<HandshakerResp, HandshakerReq>* stream,
+ const Status& status) {
+ GPR_ASSERT(!status.ok());
+ HandshakerResp response;
+ response.mutable_status()->set_code(status.error_code());
+ response.mutable_status()->set_details(status.error_message());
+ stream->Write(response);
+ return status;
+ }
+
+ HandshakerResult GetHandshakerResult() {
+ HandshakerResult result;
+ result.set_application_protocol("grpc");
+ result.set_record_protocol("ALTSRP_GCM_AES128_REKEY");
+ result.mutable_peer_identity()->set_service_account("peer_identity");
+ result.mutable_local_identity()->set_service_account("local_identity");
+ string key(1024, '\0');
+ result.set_key_data(key);
+ result.mutable_peer_rpc_versions()->mutable_max_rpc_version()->set_major(2);
+ result.mutable_peer_rpc_versions()->mutable_max_rpc_version()->set_minor(1);
+ result.mutable_peer_rpc_versions()->mutable_min_rpc_version()->set_major(2);
+ result.mutable_peer_rpc_versions()->mutable_min_rpc_version()->set_minor(1);
+ return result;
+ }
+};
+
+} // namespace gcp
+} // namespace grpc
+
+void RunServer() {
+ GPR_ASSERT(FLAGS_handshaker_port != 0);
+ std::ostringstream server_address;
+ server_address << "[::1]:" << FLAGS_handshaker_port;
+ grpc::gcp::FakeHandshakerService service;
+ grpc::ServerBuilder builder;
+ builder.AddListeningPort(server_address.str(),
+ grpc::InsecureServerCredentials());
+ builder.RegisterService(&service);
+ std::unique_ptr<grpc::Server> server(builder.BuildAndStart());
+ gpr_log(GPR_INFO, "Fake handshaker server listening on %s",
+ server_address.str().c_str());
+ server->Wait();
+}
+
+int main(int argc, char** argv) {
+ grpc::testing::InitTest(&argc, &argv, true);
+ RunServer();
+ return 0;
+}
diff --git a/test/core/tsi/alts/fake_handshaker/handshaker.proto b/test/core/tsi/alts/fake_handshaker/handshaker.proto
new file mode 100644
index 0000000..8af9abf
--- /dev/null
+++ b/test/core/tsi/alts/fake_handshaker/handshaker.proto
@@ -0,0 +1,224 @@
+// Copyright 2018 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.
+
+syntax = "proto3";
+
+import "test/core/tsi/alts/fake_handshaker/transport_security_common.proto";
+
+package grpc.gcp;
+
+option java_package = "io.grpc.alts.internal";
+
+enum HandshakeProtocol {
+ // Default value.
+ HANDSHAKE_PROTOCOL_UNSPECIFIED = 0;
+
+ // TLS handshake protocol.
+ TLS = 1;
+
+ // Application Layer Transport Security handshake protocol.
+ ALTS = 2;
+}
+
+enum NetworkProtocol {
+ NETWORK_PROTOCOL_UNSPECIFIED = 0;
+ TCP = 1;
+ UDP = 2;
+}
+
+message Endpoint {
+ // IP address. It should contain an IPv4 or IPv6 string literal, e.g.
+ // "192.168.0.1" or "2001:db8::1".
+ string ip_address = 1;
+
+ // Port number.
+ int32 port = 2;
+
+ // Network protocol (e.g., TCP, UDP) associated with this endpoint.
+ NetworkProtocol protocol = 3;
+}
+
+message Identity {
+ oneof identity_oneof {
+ // Service account of a connection endpoint.
+ string service_account = 1;
+
+ // Hostname of a connection endpoint.
+ string hostname = 2;
+ }
+}
+
+message StartClientHandshakeReq {
+ // Handshake security protocol requested by the client.
+ HandshakeProtocol handshake_security_protocol = 1;
+
+ // The application protocols supported by the client, e.g., "h2" (for http2),
+ // "grpc".
+ repeated string application_protocols = 2;
+
+ // The record protocols supported by the client, e.g.,
+ // "ALTSRP_GCM_AES128".
+ repeated string record_protocols = 3;
+
+ // (Optional) Describes which server identities are acceptable by the client.
+ // If target identities are provided and none of them matches the peer
+ // identity of the server, handshake will fail.
+ repeated Identity target_identities = 4;
+
+ // (Optional) Application may specify a local identity. Otherwise, the
+ // handshaker chooses a default local identity.
+ Identity local_identity = 5;
+
+ // (Optional) Local endpoint information of the connection to the server,
+ // such as local IP address, port number, and network protocol.
+ Endpoint local_endpoint = 6;
+
+ // (Optional) Endpoint information of the remote server, such as IP address,
+ // port number, and network protocol.
+ Endpoint remote_endpoint = 7;
+
+ // (Optional) If target name is provided, a secure naming check is performed
+ // to verify that the peer authenticated identity is indeed authorized to run
+ // the target name.
+ string target_name = 8;
+
+ // (Optional) RPC protocol versions supported by the client.
+ RpcProtocolVersions rpc_versions = 9;
+}
+
+message ServerHandshakeParameters {
+ // The record protocols supported by the server, e.g.,
+ // "ALTSRP_GCM_AES128".
+ repeated string record_protocols = 1;
+
+ // (Optional) A list of local identities supported by the server, if
+ // specified. Otherwise, the handshaker chooses a default local identity.
+ repeated Identity local_identities = 2;
+}
+
+message StartServerHandshakeReq {
+ // The application protocols supported by the server, e.g., "h2" (for http2),
+ // "grpc".
+ repeated string application_protocols = 1;
+
+ // Handshake parameters (record protocols and local identities supported by
+ // the server) mapped by the handshake protocol. Each handshake security
+ // protocol (e.g., TLS or ALTS) has its own set of record protocols and local
+ // identities. Since protobuf does not support enum as key to the map, the key
+ // to handshake_parameters is the integer value of HandshakeProtocol enum.
+ map<int32, ServerHandshakeParameters> handshake_parameters = 2;
+
+ // Bytes in out_frames returned from the peer's HandshakerResp. It is possible
+ // that the peer's out_frames are split into multiple HandshakReq messages.
+ bytes in_bytes = 3;
+
+ // (Optional) Local endpoint information of the connection to the client,
+ // such as local IP address, port number, and network protocol.
+ Endpoint local_endpoint = 4;
+
+ // (Optional) Endpoint information of the remote client, such as IP address,
+ // port number, and network protocol.
+ Endpoint remote_endpoint = 5;
+
+ // (Optional) RPC protocol versions supported by the server.
+ RpcProtocolVersions rpc_versions = 6;
+}
+
+message NextHandshakeMessageReq {
+ // Bytes in out_frames returned from the peer's HandshakerResp. It is possible
+ // that the peer's out_frames are split into multiple NextHandshakerMessageReq
+ // messages.
+ bytes in_bytes = 1;
+}
+
+message HandshakerReq {
+ oneof req_oneof {
+ // The start client handshake request message.
+ StartClientHandshakeReq client_start = 1;
+
+ // The start server handshake request message.
+ StartServerHandshakeReq server_start = 2;
+
+ // The next handshake request message.
+ NextHandshakeMessageReq next = 3;
+ }
+}
+
+message HandshakerResult {
+ // The application protocol negotiated for this connection.
+ string application_protocol = 1;
+
+ // The record protocol negotiated for this connection.
+ string record_protocol = 2;
+
+ // Cryptographic key data. The key data may be more than the key length
+ // required for the record protocol, thus the client of the handshaker
+ // service needs to truncate the key data into the right key length.
+ bytes key_data = 3;
+
+ // The authenticated identity of the peer.
+ Identity peer_identity = 4;
+
+ // The local identity used in the handshake.
+ Identity local_identity = 5;
+
+ // Indicate whether the handshaker service client should keep the channel
+ // between the handshaker service open, e.g., in order to handle
+ // post-handshake messages in the future.
+ bool keep_channel_open = 6;
+
+ // The RPC protocol versions supported by the peer.
+ RpcProtocolVersions peer_rpc_versions = 7;
+}
+
+message HandshakerStatus {
+ // The status code. This could be the gRPC status code.
+ uint32 code = 1;
+
+ // The status details.
+ string details = 2;
+}
+
+message HandshakerResp {
+ // Frames to be given to the peer for the NextHandshakeMessageReq. May be
+ // empty if no out_frames have to be sent to the peer or if in_bytes in the
+ // HandshakerReq are incomplete. All the non-empty out frames must be sent to
+ // the peer even if the handshaker status is not OK as these frames may
+ // contain the alert frames.
+ bytes out_frames = 1;
+
+ // Number of bytes in the in_bytes consumed by the handshaker. It is possible
+ // that part of in_bytes in HandshakerReq was unrelated to the handshake
+ // process.
+ uint32 bytes_consumed = 2;
+
+ // This is set iff the handshake was successful. out_frames may still be set
+ // to frames that needs to be forwarded to the peer.
+ HandshakerResult result = 3;
+
+ // Status of the handshaker.
+ HandshakerStatus status = 4;
+}
+
+service HandshakerService {
+ // Handshaker service accepts a stream of handshaker request, returning a
+ // stream of handshaker response. Client is expected to send exactly one
+ // message with either client_start or server_start followed by one or more
+ // messages with next. Each time client sends a request, the handshaker
+ // service expects to respond. Client does not have to wait for service's
+ // response before sending next request.
+ rpc DoHandshake(stream HandshakerReq)
+ returns (stream HandshakerResp) {
+ }
+}
diff --git a/test/core/tsi/alts/fake_handshaker/transport_security_common.proto b/test/core/tsi/alts/fake_handshaker/transport_security_common.proto
new file mode 100644
index 0000000..d0f861e
--- /dev/null
+++ b/test/core/tsi/alts/fake_handshaker/transport_security_common.proto
@@ -0,0 +1,40 @@
+// Copyright 2018 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.
+
+syntax = "proto3";
+
+package grpc.gcp;
+
+option java_package = "io.grpc.alts.internal";
+
+// The security level of the created channel. The list is sorted in increasing
+// level of security. This order must always be maintained.
+enum SecurityLevel {
+ SECURITY_NONE = 0;
+ INTEGRITY_ONLY = 1;
+ INTEGRITY_AND_PRIVACY = 2;
+}
+
+// Max and min supported RPC protocol versions.
+message RpcProtocolVersions {
+ // RPC version contains a major version and a minor version.
+ message Version {
+ uint32 major = 1;
+ uint32 minor = 2;
+ }
+ // Maximum supported RPC version.
+ Version max_rpc_version = 1;
+ // Minimum supported RPC version.
+ Version min_rpc_version = 2;
+}
diff --git a/test/core/tsi/alts/frame_protector/BUILD b/test/core/tsi/alts/frame_protector/BUILD
index 94c2ab3..dd1966b 100644
--- a/test/core/tsi/alts/frame_protector/BUILD
+++ b/test/core/tsi/alts/frame_protector/BUILD
@@ -16,7 +16,7 @@
licenses(["notice"]) # Apache v2
-grpc_package(name = "frame_protector")
+grpc_package(name = "test/core/tsi/alts/frame_protector")
grpc_cc_test(
name = "alts_counter_test",
diff --git a/test/core/tsi/alts/handshaker/BUILD b/test/core/tsi/alts/handshaker/BUILD
index fc2c395..8097427 100644
--- a/test/core/tsi/alts/handshaker/BUILD
+++ b/test/core/tsi/alts/handshaker/BUILD
@@ -16,7 +16,7 @@
licenses(["notice"]) # Apache v2
-grpc_package(name = "handshaker")
+grpc_package(name = "test/core/tsi/alts/handshaker")
grpc_cc_library(
name = "alts_handshaker_service_api_test_lib",
diff --git a/test/core/tsi/alts/handshaker/alts_handshaker_client_test.cc b/test/core/tsi/alts/handshaker/alts_handshaker_client_test.cc
index 7072be6..c8d88aa 100644
--- a/test/core/tsi/alts/handshaker/alts_handshaker_client_test.cc
+++ b/test/core/tsi/alts/handshaker/alts_handshaker_client_test.cc
@@ -54,11 +54,9 @@
: grpc_alts_credentials_server_options_create();
if (is_client) {
grpc_alts_credentials_client_options_add_target_service_account(
- reinterpret_cast<grpc_alts_credentials_client_options*>(e->options),
- ALTS_HANDSHAKER_CLIENT_TEST_TARGET_SERVICE_ACCOUNT1);
+ e->options, ALTS_HANDSHAKER_CLIENT_TEST_TARGET_SERVICE_ACCOUNT1);
grpc_alts_credentials_client_options_add_target_service_account(
- reinterpret_cast<grpc_alts_credentials_client_options*>(e->options),
- ALTS_HANDSHAKER_CLIENT_TEST_TARGET_SERVICE_ACCOUNT2);
+ e->options, ALTS_HANDSHAKER_CLIENT_TEST_TARGET_SERVICE_ACCOUNT2);
}
grpc_gcp_rpc_protocol_versions* versions = &e->options->rpc_versions;
GPR_ASSERT(grpc_gcp_rpc_protocol_versions_set_max(
@@ -328,6 +326,9 @@
GPR_ASSERT(alts_handshaker_client_next(nullptr, event, &config->out_frame) ==
TSI_INVALID_ARGUMENT);
+ /* Check shutdown. */
+ alts_handshaker_client_shutdown(nullptr);
+
/* Cleanup. */
alts_tsi_event_destroy(event);
destroy_config(config);
diff --git a/test/core/tsi/alts/handshaker/alts_tsi_handshaker_test.cc b/test/core/tsi/alts/handshaker/alts_tsi_handshaker_test.cc
index 95724f8..85a5811 100644
--- a/test/core/tsi/alts/handshaker/alts_tsi_handshaker_test.cc
+++ b/test/core/tsi/alts/handshaker/alts_tsi_handshaker_test.cc
@@ -330,6 +330,8 @@
return TSI_OK;
}
+static void mock_shutdown(alts_handshaker_client* self) {}
+
static tsi_result mock_server_start(alts_handshaker_client* self,
alts_tsi_event* event,
grpc_slice* bytes_received) {
@@ -400,7 +402,8 @@
static void mock_destruct(alts_handshaker_client* client) {}
static const alts_handshaker_client_vtable vtable = {
- mock_client_start, mock_server_start, mock_next, mock_destruct};
+ mock_client_start, mock_server_start, mock_next, mock_shutdown,
+ mock_destruct};
static alts_handshaker_client* alts_mock_handshaker_client_create(
bool used_for_success_test) {
@@ -442,6 +445,16 @@
tsi_handshaker_destroy(handshaker);
}
+static void check_handshaker_shutdown_invalid_input() {
+ /* Initialization. */
+ tsi_handshaker* handshaker = create_test_handshaker(
+ false /* used_for_success_test */, true /* is_client */);
+ /* Check nullptr handshaker. */
+ tsi_handshaker_shutdown(nullptr);
+ /* Cleanup. */
+ tsi_handshaker_destroy(handshaker);
+}
+
static void check_handshaker_next_success() {
/**
* Create handshakers for which internal mock client is going to do
@@ -480,6 +493,33 @@
tsi_handshaker_destroy(client_handshaker);
}
+static void check_handshaker_next_with_shutdown() {
+ /* Initialization. */
+ tsi_handshaker* handshaker = create_test_handshaker(
+ true /* used_for_success_test */, true /* is_client*/);
+ /* next(success) -- shutdown(success) -- next (fail) */
+ GPR_ASSERT(tsi_handshaker_next(handshaker, nullptr, 0, nullptr, nullptr,
+ nullptr, on_client_start_success_cb,
+ nullptr) == TSI_ASYNC);
+ wait(&tsi_to_caller_notification);
+ tsi_handshaker_shutdown(handshaker);
+ GPR_ASSERT(tsi_handshaker_next(
+ handshaker,
+ (const unsigned char*)ALTS_TSI_HANDSHAKER_TEST_RECV_BYTES,
+ strlen(ALTS_TSI_HANDSHAKER_TEST_RECV_BYTES), nullptr, nullptr,
+ nullptr, on_client_next_success_cb,
+ nullptr) == TSI_HANDSHAKE_SHUTDOWN);
+ /* Cleanup. */
+ tsi_handshaker_destroy(handshaker);
+}
+
+static void check_handle_response_with_shutdown(void* unused) {
+ /* Client start. */
+ wait(&caller_to_tsi_notification);
+ alts_tsi_event_dispatch_to_handshaker(client_start_event, true /* is_ok */);
+ alts_tsi_event_destroy(client_start_event);
+}
+
static void check_handshaker_next_failure() {
/**
* Create handshakers for which internal mock client is always going to fail.
@@ -647,6 +687,49 @@
tsi_handshaker_destroy(handshaker);
}
+static void on_shutdown_resp_cb(tsi_result status, void* user_data,
+ const unsigned char* bytes_to_send,
+ size_t bytes_to_send_size,
+ tsi_handshaker_result* result) {
+ GPR_ASSERT(status == TSI_HANDSHAKE_SHUTDOWN);
+ GPR_ASSERT(user_data == nullptr);
+ GPR_ASSERT(bytes_to_send == nullptr);
+ GPR_ASSERT(bytes_to_send_size == 0);
+ GPR_ASSERT(result == nullptr);
+}
+
+static void check_handle_response_after_shutdown() {
+ tsi_handshaker* handshaker = create_test_handshaker(
+ true /* used_for_success_test */, true /* is_client */);
+ alts_tsi_handshaker* alts_handshaker =
+ reinterpret_cast<alts_tsi_handshaker*>(handshaker);
+ /* Tests. */
+ tsi_handshaker_shutdown(handshaker);
+ grpc_byte_buffer* recv_buffer = generate_handshaker_response(CLIENT_START);
+ alts_tsi_handshaker_handle_response(alts_handshaker, recv_buffer,
+ GRPC_STATUS_OK, nullptr,
+ on_shutdown_resp_cb, nullptr, true);
+ grpc_byte_buffer_destroy(recv_buffer);
+ /* Cleanup. */
+ tsi_handshaker_destroy(handshaker);
+}
+
+void check_handshaker_next_fails_after_shutdown() {
+ /* Initialization. */
+ notification_init(&caller_to_tsi_notification);
+ notification_init(&tsi_to_caller_notification);
+ client_start_event = nullptr;
+ /* Tests. */
+ grpc_core::Thread thd("alts_tsi_handshaker_test",
+ &check_handle_response_with_shutdown, nullptr);
+ thd.Start();
+ check_handshaker_next_with_shutdown();
+ thd.Join();
+ /* Cleanup. */
+ notification_destroy(&caller_to_tsi_notification);
+ notification_destroy(&tsi_to_caller_notification);
+}
+
void check_handshaker_success() {
/* Initialization. */
notification_init(&caller_to_tsi_notification);
@@ -672,10 +755,13 @@
/* Tests. */
check_handshaker_success();
check_handshaker_next_invalid_input();
+ check_handshaker_shutdown_invalid_input();
+ check_handshaker_next_fails_after_shutdown();
check_handshaker_next_failure();
check_handle_response_invalid_input();
check_handle_response_invalid_resp();
check_handle_response_failure();
+ check_handle_response_after_shutdown();
/* Cleanup. */
grpc_shutdown();
return 0;
diff --git a/test/core/tsi/alts/zero_copy_frame_protector/BUILD b/test/core/tsi/alts/zero_copy_frame_protector/BUILD
index 4c6fb91..2b41dae 100644
--- a/test/core/tsi/alts/zero_copy_frame_protector/BUILD
+++ b/test/core/tsi/alts/zero_copy_frame_protector/BUILD
@@ -16,7 +16,7 @@
licenses(["notice"]) # Apache v2
-grpc_package(name = "zero_copy_frame_protector")
+grpc_package(name = "test/core/tsi/alts/zero_copy_frame_protector")
grpc_cc_test(
name = "alts_grpc_record_protocol_test",
diff --git a/test/core/tsi/ssl_session_cache_test.cc b/test/core/tsi/ssl_session_cache_test.cc
index 72df0e5..c86cefb 100644
--- a/test/core/tsi/ssl_session_cache_test.cc
+++ b/test/core/tsi/ssl_session_cache_test.cc
@@ -88,7 +88,6 @@
// Verify session initial state.
{
tsi::SslSessionPtr tmp_sess = tracker.NewSession(1);
- EXPECT_EQ(tmp_sess->references, 1);
EXPECT_TRUE(tracker.IsAlive(1));
EXPECT_EQ(tracker.AliveCount(), 1);
}
diff --git a/test/core/tsi/ssl_transport_security_test.cc b/test/core/tsi/ssl_transport_security_test.cc
index 88f1abc..b477904 100644
--- a/test/core/tsi/ssl_transport_security_test.cc
+++ b/test/core/tsi/ssl_transport_security_test.cc
@@ -24,7 +24,6 @@
#include "src/core/lib/security/security_connector/security_connector.h"
#include "src/core/tsi/ssl_transport_security.h"
#include "src/core/tsi/transport_security.h"
-#include "src/core/tsi/transport_security_adapter.h"
#include "src/core/tsi/transport_security_interface.h"
#include "test/core/tsi/transport_security_test_lib.h"
#include "test/core/util/test_config.h"
@@ -34,6 +33,10 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
+extern "C" {
+#include <openssl/crypto.h>
+}
+
#define SSL_TSI_TEST_ALPN1 "foo"
#define SSL_TSI_TEST_ALPN2 "toto"
#define SSL_TSI_TEST_ALPN3 "baz"
@@ -42,6 +45,14 @@
#define SSL_TSI_TEST_BAD_SERVER_KEY_CERT_PAIRS_NUM 1
#define SSL_TSI_TEST_CREDENTIALS_DIR "src/core/tsi/test_creds/"
+// OpenSSL 1.1 uses AES256 for encryption session ticket by default so specify
+// different STEK size.
+#if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(OPENSSL_IS_BORINGSSL)
+const size_t kSessionTicketEncryptionKeySize = 80;
+#else
+const size_t kSessionTicketEncryptionKeySize = 48;
+#endif
+
typedef enum AlpnMode {
NO_ALPN,
ALPN_CLIENT_NO_SERVER,
@@ -152,19 +163,13 @@
&server_options, &ssl_fixture->server_handshaker_factory) ==
TSI_OK);
/* Create server and client handshakers. */
- tsi_handshaker* client_handshaker = nullptr;
GPR_ASSERT(tsi_ssl_client_handshaker_factory_create_handshaker(
ssl_fixture->client_handshaker_factory,
ssl_fixture->server_name_indication,
- &client_handshaker) == TSI_OK);
- ssl_fixture->base.client_handshaker =
- tsi_create_adapter_handshaker(client_handshaker);
- tsi_handshaker* server_handshaker = nullptr;
+ &ssl_fixture->base.client_handshaker) == TSI_OK);
GPR_ASSERT(tsi_ssl_server_handshaker_factory_create_handshaker(
- ssl_fixture->server_handshaker_factory, &server_handshaker) ==
- TSI_OK);
- ssl_fixture->base.server_handshaker =
- tsi_create_adapter_handshaker(server_handshaker);
+ ssl_fixture->server_handshaker_factory,
+ &ssl_fixture->base.server_handshaker) == TSI_OK);
}
static void check_alpn(ssl_tsi_test_fixture* ssl_fixture,
@@ -624,7 +629,7 @@
void ssl_tsi_test_do_handshake_session_cache() {
tsi_ssl_session_cache* session_cache = tsi_ssl_session_cache_create_lru(16);
- char session_ticket_key[48];
+ char session_ticket_key[kSessionTicketEncryptionKeySize];
auto do_handshake = [&session_ticket_key,
&session_cache](bool session_reused) {
tsi_test_fixture* fixture = ssl_tsi_test_fixture_create();
@@ -633,22 +638,22 @@
ssl_fixture->server_name_indication =
const_cast<char*>("waterzooi.test.google.be");
ssl_fixture->session_ticket_key = session_ticket_key;
- ssl_fixture->session_ticket_key_size = 48;
+ ssl_fixture->session_ticket_key_size = sizeof(session_ticket_key);
tsi_ssl_session_cache_ref(session_cache);
ssl_fixture->session_cache = session_cache;
ssl_fixture->session_reused = session_reused;
tsi_test_do_round_trip(&ssl_fixture->base);
tsi_test_fixture_destroy(fixture);
};
- memset(session_ticket_key, 'a', 48);
+ memset(session_ticket_key, 'a', sizeof(session_ticket_key));
do_handshake(false);
do_handshake(true);
do_handshake(true);
// Changing session_ticket_key on server invalidates ticket.
- memset(session_ticket_key, 'b', 48);
+ memset(session_ticket_key, 'b', sizeof(session_ticket_key));
do_handshake(false);
do_handshake(true);
- memset(session_ticket_key, 'c', 48);
+ memset(session_ticket_key, 'c', sizeof(session_ticket_key));
do_handshake(false);
do_handshake(true);
tsi_ssl_session_cache_unref(session_cache);
diff --git a/test/core/util/BUILD b/test/core/util/BUILD
index 886cfdd..f52570c 100644
--- a/test/core/util/BUILD
+++ b/test/core/util/BUILD
@@ -52,6 +52,7 @@
name = "grpc_test_util_base",
srcs = [
"cmdline.cc",
+ "fuzzer_util.cc",
"grpc_profiler.cc",
"histogram.cc",
"mock_endpoint.cc",
@@ -70,6 +71,7 @@
],
hdrs = [
"cmdline.h",
+ "fuzzer_util.h",
"grpc_profiler.h",
"histogram.h",
"mock_endpoint.h",
diff --git a/test/core/util/fuzzer_corpus_test.cc b/test/core/util/fuzzer_corpus_test.cc
index 18bc0ad..ebf1913 100644
--- a/test/core/util/fuzzer_corpus_test.cc
+++ b/test/core/util/fuzzer_corpus_test.cc
@@ -20,6 +20,7 @@
#include <dirent.h>
#include <gflags/gflags.h>
+#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <gtest/gtest.h>
#include <stdio.h>
@@ -91,6 +92,7 @@
perror("Couldn't open the directory");
abort();
}
+ gpr_free(test_srcdir);
}
}
}
diff --git a/test/core/util/fuzzer_util.cc b/test/core/util/fuzzer_util.cc
new file mode 100644
index 0000000..29c9b88
--- /dev/null
+++ b/test/core/util/fuzzer_util.cc
@@ -0,0 +1,82 @@
+/*
+ *
+ * Copyright 2018 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.
+ *
+ */
+
+#include "test/core/util/fuzzer_util.h"
+
+#include <grpc/support/alloc.h>
+
+#include "src/core/lib/gpr/useful.h"
+
+namespace grpc_core {
+namespace testing {
+
+uint8_t grpc_fuzzer_get_next_byte(input_stream* inp) {
+ if (inp->cur == inp->end) {
+ return 0;
+ }
+ return *inp->cur++;
+}
+
+char* grpc_fuzzer_get_next_string(input_stream* inp, bool* special) {
+ char* str = nullptr;
+ size_t cap = 0;
+ size_t sz = 0;
+ char c;
+ do {
+ if (cap == sz) {
+ cap = GPR_MAX(3 * cap / 2, cap + 8);
+ str = static_cast<char*>(gpr_realloc(str, cap));
+ }
+ c = static_cast<char>(grpc_fuzzer_get_next_byte(inp));
+ str[sz++] = c;
+ } while (c != 0 && c != 1);
+ if (special != nullptr) {
+ *special = (c == 1);
+ }
+ if (c == 1) {
+ str[sz - 1] = 0;
+ }
+ return str;
+}
+
+uint32_t grpc_fuzzer_get_next_uint32(input_stream* inp) {
+ uint8_t b = grpc_fuzzer_get_next_byte(inp);
+ uint32_t x = b & 0x7f;
+ if (b & 0x80) {
+ x <<= 7;
+ b = grpc_fuzzer_get_next_byte(inp);
+ x |= b & 0x7f;
+ if (b & 0x80) {
+ x <<= 7;
+ b = grpc_fuzzer_get_next_byte(inp);
+ x |= b & 0x7f;
+ if (b & 0x80) {
+ x <<= 7;
+ b = grpc_fuzzer_get_next_byte(inp);
+ x |= b & 0x7f;
+ if (b & 0x80) {
+ x = (x << 4) | (grpc_fuzzer_get_next_byte(inp) & 0x0f);
+ }
+ }
+ }
+ }
+ return x;
+}
+
+} // namespace testing
+} // namespace grpc_core
diff --git a/test/core/util/fuzzer_util.h b/test/core/util/fuzzer_util.h
new file mode 100644
index 0000000..0e93839
--- /dev/null
+++ b/test/core/util/fuzzer_util.h
@@ -0,0 +1,49 @@
+/*
+ *
+ * Copyright 2018 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_TEST_CORE_UTIL_FUZZER_UTIL_H
+#define GRPC_TEST_CORE_UTIL_FUZZER_UTIL_H
+
+#include <stdint.h>
+
+namespace grpc_core {
+
+namespace testing {
+
+// Main struct for input_stream. It allows easy access to input
+// bytes, and allows reading a little past the end(avoiding
+// needing to check everywhere).
+typedef struct {
+ const uint8_t* cur;
+ const uint8_t* end;
+} input_stream;
+
+// get a byte from an input stream.
+uint8_t grpc_fuzzer_get_next_byte(input_stream* inp);
+
+// get a string and boolean values (if special is not null) from an input
+// stream.
+char* grpc_fuzzer_get_next_string(input_stream* inp, bool* special);
+
+// get a uint32 value from an input stream.
+uint32_t grpc_fuzzer_get_next_uint32(input_stream* inp);
+
+} // namespace testing
+} // namespace grpc_core
+
+#endif /* GRPC_TEST_CORE_UTIL_FUZZER_UTIL_H */
diff --git a/test/cpp/cocoapods/generic/generic.mm b/test/cpp/cocoapods/generic/generic.mm
index 6e65176..6740e9c 100644
--- a/test/cpp/cocoapods/generic/generic.mm
+++ b/test/cpp/cocoapods/generic/generic.mm
@@ -20,6 +20,8 @@
#include <sstream>
+#include <grpc/grpc.h>
+#include <grpc/support/time.h>
#include <grpcpp/channel.h>
#include <grpcpp/client_context.h>
#include <grpcpp/create_channel.h>
@@ -29,8 +31,6 @@
#include <grpcpp/server_builder.h>
#include <grpcpp/server_context.h>
#include <grpcpp/support/slice.h>
-#include <grpc/grpc.h>
-#include <grpc/support/time.h>
#include "src/core/lib/gprpp/thd.h"
#include "test/core/util/port.h"
@@ -55,8 +55,7 @@
cursor = GRPC_SLICE_START_PTR(out);
for (i = 0; i < nslices; i++) {
- memcpy(cursor, GRPC_SLICE_START_PTR(slices[i]),
- GRPC_SLICE_LENGTH(slices[i]));
+ memcpy(cursor, GRPC_SLICE_START_PTR(slices[i]), GRPC_SLICE_LENGTH(slices[i]));
cursor += GRPC_SLICE_LENGTH(slices[i]);
}
@@ -74,16 +73,14 @@
}
grpc_slice a = merge_slices(c_slices, slices.size());
grpc_slice b = grpc_slice_from_copied_string(str);
- res =
- (GRPC_SLICE_LENGTH(a) == GRPC_SLICE_LENGTH(b)) &&
- (0 == memcmp(GRPC_SLICE_START_PTR(a), GRPC_SLICE_START_PTR(b),
- GRPC_SLICE_LENGTH(a)));
+ res = (GRPC_SLICE_LENGTH(a) == GRPC_SLICE_LENGTH(b)) &&
+ (0 == memcmp(GRPC_SLICE_START_PTR(a), GRPC_SLICE_START_PTR(b), GRPC_SLICE_LENGTH(a)));
grpc_slice_unref(a);
grpc_slice_unref(b);
for (int i = 0; i < slices.size(); i++) {
grpc_slice_unref(c_slices[i]);
}
- delete [] c_slices;
+ delete[] c_slices;
return res;
}
@@ -102,9 +99,7 @@
std::ostringstream server_address_;
}
-- (void)verify_ok:(grpc::CompletionQueue*)cq
- i:(int)i
- expect_ok:(bool)expect_ok {
+- (void)verify_ok:(grpc::CompletionQueue*)cq i:(int)i expect_ok:(bool)expect_ok {
bool ok;
void* got_tag;
XCTAssertTrue(cq->Next(&got_tag, &ok));
@@ -112,10 +107,18 @@
XCTAssertEqual(tag(i), got_tag);
}
-- (void)server_ok:(int)i { [self verify_ok:srv_cq_.get() i:i expect_ok:true]; }
-- (void)client_ok:(int)i { [self verify_ok:&cli_cq_ i:i expect_ok:true]; }
-- (void)server_fail:(int)i { [self verify_ok:srv_cq_.get() i:i expect_ok:false]; }
-- (void)client_fail:(int)i { [self verify_ok:&cli_cq_ i:i expect_ok:false]; }
+- (void)server_ok:(int)i {
+ [self verify_ok:srv_cq_.get() i:i expect_ok:true];
+}
+- (void)client_ok:(int)i {
+ [self verify_ok:&cli_cq_ i:i expect_ok:true];
+}
+- (void)server_fail:(int)i {
+ [self verify_ok:srv_cq_.get() i:i expect_ok:false];
+}
+- (void)client_fail:(int)i {
+ [self verify_ok:&cli_cq_ i:i expect_ok:false];
+}
- (void)setUp {
[super setUp];
@@ -125,8 +128,7 @@
server_address_ << server_host_ << ":" << port;
// Setup server
ServerBuilder builder;
- builder.AddListeningPort(server_address_.str(),
- InsecureServerCredentials());
+ builder.AddListeningPort(server_address_.str(), InsecureServerCredentials());
builder.RegisterAsyncGenericService(&generic_service_);
// Include a second call to RegisterAsyncGenericService to make sure that
// we get an error in the log, since it is not allowed to have 2 async
@@ -137,14 +139,17 @@
}
- (void)tearDown {
- // Put teardown code here. This method is called after the invocation of each test method in the class.
+ // Put teardown code here. This method is called after the invocation of each test method in the
+ // class.
server_->Shutdown();
void* ignored_tag;
bool ignored_ok;
cli_cq_.Shutdown();
srv_cq_->Shutdown();
- while (cli_cq_.Next(&ignored_tag, &ignored_ok));
- while (srv_cq_->Next(&ignored_tag, &ignored_ok));
+ while (cli_cq_.Next(&ignored_tag, &ignored_ok))
+ ;
+ while (srv_cq_->Next(&ignored_tag, &ignored_ok))
+ ;
[super tearDown];
}
@@ -156,11 +161,9 @@
- (void)SendRpc:(int)num_rpcs {
[self SendRpc:num_rpcs check_deadline:false deadline:gpr_inf_future(GPR_CLOCK_MONOTONIC)];
- }
+}
-- (void)SendRpc:(int)num_rpcs
- check_deadline:(bool)check_deadline
- deadline:(gpr_timespec)deadline {
+- (void)SendRpc:(int)num_rpcs check_deadline:(bool)check_deadline deadline:(gpr_timespec)deadline {
const grpc::string kMethodName("/grpc.cpp.test.util.EchoTestService/Echo");
for (int i = 0; i < num_rpcs; i++) {
Status recv_status;
@@ -177,7 +180,7 @@
}
std::unique_ptr<GenericClientAsyncReaderWriter> call =
- generic_stub_->Call(&cli_ctx, kMethodName, &cli_cq_, tag(1));
+ generic_stub_->Call(&cli_ctx, kMethodName, &cli_cq_, tag(1));
[self client_ok:1];
Slice send_slice = Slice("hello world", 11);
std::unique_ptr<ByteBuffer> send_buffer =
@@ -189,8 +192,7 @@
call->WritesDone(tag(3));
[self client_ok:3];
- generic_service_.RequestCall(&srv_ctx, &stream, srv_cq_.get(),
- srv_cq_.get(), tag(4));
+ generic_service_.RequestCall(&srv_ctx, &stream, srv_cq_.get(), srv_cq_.get(), tag(4));
[self verify_ok:srv_cq_.get() i:4 expect_ok:true];
XCTAssertEqual(server_host_, srv_ctx.host().substr(0, server_host_.length()));
@@ -198,7 +200,7 @@
if (check_deadline) {
XCTAssertTrue(gpr_time_similar(deadline, srv_ctx.raw_deadline(),
- gpr_time_from_millis(1000, GPR_TIMESPAN)));
+ gpr_time_from_millis(1000, GPR_TIMESPAN)));
}
ByteBuffer recv_buffer;
@@ -241,4 +243,3 @@
}
@end
-
diff --git a/test/cpp/cocoapods/test/server_context_test_spouse_test.mm b/test/cpp/cocoapods/test/server_context_test_spouse_test.mm
index 7cb1b36..59f60e3 100644
--- a/test/cpp/cocoapods/test/server_context_test_spouse_test.mm
+++ b/test/cpp/cocoapods/test/server_context_test_spouse_test.mm
@@ -18,7 +18,7 @@
// Hack TEST macro of gTest and make they conform XCTest style. We only
// need test name (b), not test case name (a).
-#define TEST(a,b) - (void)test ## b
+#define TEST(a, b) -(void)test##b
#define ASSERT_TRUE XCTAssert
#define ASSERT_EQ XCTAssertEqual
@@ -38,12 +38,10 @@
const char val1[] = "metadata-val1";
const char val2[] = "metadata-val2";
-bool ClientMetadataContains(const grpc::ServerContext& context,
- const grpc::string_ref& key,
+bool ClientMetadataContains(const grpc::ServerContext& context, const grpc::string_ref& key,
const grpc::string_ref& value) {
const auto& client_metadata = context.client_metadata();
- for (auto iter = client_metadata.begin(); iter != client_metadata.end();
- ++iter) {
+ for (auto iter = client_metadata.begin(); iter != client_metadata.end(); ++iter) {
if (iter->first == key && iter->second == value) {
return true;
}
diff --git a/test/cpp/codegen/proto_utils_test.cc b/test/cpp/codegen/proto_utils_test.cc
index 836d3d8..801660e 100644
--- a/test/cpp/codegen/proto_utils_test.cc
+++ b/test/cpp/codegen/proto_utils_test.cc
@@ -24,32 +24,42 @@
#include <gtest/gtest.h>
namespace grpc {
+
namespace internal {
-// Provide access to GrpcBufferWriter internals.
-class GrpcBufferWriterPeer {
+// Provide access to ProtoBufferWriter internals.
+class ProtoBufferWriterPeer {
public:
- explicit GrpcBufferWriterPeer(internal::GrpcBufferWriter* writer)
- : writer_(writer) {}
+ explicit ProtoBufferWriterPeer(ProtoBufferWriter* writer) : writer_(writer) {}
bool have_backup() const { return writer_->have_backup_; }
const grpc_slice& backup_slice() const { return writer_->backup_slice_; }
const grpc_slice& slice() const { return writer_->slice_; }
private:
- GrpcBufferWriter* writer_;
+ ProtoBufferWriter* writer_;
+};
+
+// Provide access to ByteBuffer internals.
+class GrpcByteBufferPeer {
+ public:
+ explicit GrpcByteBufferPeer(ByteBuffer* bb) : bb_(bb) {}
+ grpc_byte_buffer* c_buffer() { return bb_->c_buffer(); }
+
+ private:
+ ByteBuffer* bb_;
};
class ProtoUtilsTest : public ::testing::Test {};
// Regression test for a memory corruption bug where a series of
-// GrpcBufferWriter Next()/Backup() invocations could result in a dangling
+// ProtoBufferWriter Next()/Backup() invocations could result in a dangling
// pointer returned by Next() due to the interaction between grpc_slice inlining
// and GRPC_SLICE_START_PTR.
TEST_F(ProtoUtilsTest, TinyBackupThenNext) {
- grpc_byte_buffer* bp;
+ ByteBuffer bp;
const int block_size = 1024;
- GrpcBufferWriter writer(&bp, block_size, 8192);
- GrpcBufferWriterPeer peer(&writer);
+ ProtoBufferWriter writer(&bp, block_size, 8192);
+ ProtoBufferWriterPeer peer(&writer);
void* data;
int size;
@@ -63,17 +73,14 @@
ASSERT_TRUE(writer.Next(&data, &size));
EXPECT_TRUE(peer.slice().refcount != nullptr);
EXPECT_EQ(block_size, size);
-
- // Cleanup.
- g_core_codegen_interface->grpc_byte_buffer_destroy(bp);
}
namespace {
// Set backup_size to 0 to indicate no backup is needed.
void BufferWriterTest(int block_size, int total_size, int backup_size) {
- grpc_byte_buffer* bp;
- GrpcBufferWriter writer(&bp, block_size, total_size);
+ ByteBuffer bb;
+ ProtoBufferWriter writer(&bb, block_size, total_size);
int written_size = 0;
void* data;
@@ -110,10 +117,11 @@
writer.BackUp(backup_size);
}
}
- EXPECT_EQ(grpc_byte_buffer_length(bp), (size_t)total_size);
+ EXPECT_EQ(bb.Length(), (size_t)total_size);
grpc_byte_buffer_reader reader;
- grpc_byte_buffer_reader_init(&reader, bp);
+ GrpcByteBufferPeer peer(&bb);
+ grpc_byte_buffer_reader_init(&reader, peer.c_buffer());
int read_bytes = 0;
while (read_bytes < total_size) {
grpc_slice s;
@@ -126,7 +134,6 @@
}
EXPECT_EQ(read_bytes, total_size);
grpc_byte_buffer_reader_destroy(&reader);
- grpc_byte_buffer_destroy(bp);
}
TEST(WriterTest, TinyBlockTinyBackup) {
@@ -154,7 +161,7 @@
} // namespace grpc
int main(int argc, char** argv) {
- // Ensure the GrpcBufferWriter internals are initialized.
+ // Ensure the ProtoBufferWriter internals are initialized.
grpc::internal::GrpcLibraryInitializer init;
init.summon();
grpc::GrpcLibraryCodegen lib;
diff --git a/test/cpp/common/alarm_test.cc b/test/cpp/common/alarm_test.cc
index fb5f671..57d9583 100644
--- a/test/cpp/common/alarm_test.cc
+++ b/test/cpp/common/alarm_test.cc
@@ -36,7 +36,7 @@
void* output_tag;
bool ok;
const CompletionQueue::NextStatus status =
- cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(2));
+ cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(10));
EXPECT_EQ(status, CompletionQueue::GOT_EVENT);
EXPECT_TRUE(ok);
@@ -57,7 +57,7 @@
std::thread t2([&cq, &ok, &output_tag, &status] {
status =
- cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(2));
+ cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(10));
});
t1.join();
@@ -75,7 +75,7 @@
void* output_tag;
bool ok;
const CompletionQueue::NextStatus status =
- cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(2));
+ cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(10));
EXPECT_EQ(status, CompletionQueue::GOT_EVENT);
EXPECT_TRUE(ok);
@@ -91,7 +91,7 @@
void* output_tag;
bool ok;
const CompletionQueue::NextStatus status =
- cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(2));
+ cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(10));
EXPECT_EQ(status, CompletionQueue::GOT_EVENT);
EXPECT_TRUE(ok);
EXPECT_EQ(junk, output_tag);
@@ -108,7 +108,7 @@
void* output_tag;
bool ok;
const CompletionQueue::NextStatus status =
- cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(2));
+ cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(10));
EXPECT_EQ(status, CompletionQueue::GOT_EVENT);
EXPECT_TRUE(ok);
@@ -126,7 +126,7 @@
void* output_tag;
bool ok;
const CompletionQueue::NextStatus status =
- cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(2));
+ cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(10));
EXPECT_EQ(status, CompletionQueue::GOT_EVENT);
EXPECT_TRUE(ok);
@@ -169,7 +169,7 @@
CompletionQueue cq;
void* junk = reinterpret_cast<void*>(1618033);
Alarm alarm;
- alarm.Set(&cq, grpc_timeout_seconds_to_deadline(2), junk);
+ alarm.Set(&cq, grpc_timeout_seconds_to_deadline(10), junk);
alarm.Cancel();
void* output_tag;
@@ -187,7 +187,7 @@
void* junk = reinterpret_cast<void*>(1618033);
{
Alarm alarm;
- alarm.Set(&cq, grpc_timeout_seconds_to_deadline(2), junk);
+ alarm.Set(&cq, grpc_timeout_seconds_to_deadline(10), junk);
}
void* output_tag;
diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc
index 5578456..7aab035 100644
--- a/test/cpp/end2end/grpclb_end2end_test.cc
+++ b/test/cpp/end2end/grpclb_end2end_test.cc
@@ -1139,7 +1139,7 @@
EXPECT_EQ(0U, backend_servers_[1].service_->request_count());
WaitForBackend(1);
- // This is serviced by the existing RR policy
+ // This is serviced by the updated RR policy
backend_servers_[1].service_->ResetCounters();
gpr_log(GPR_INFO, "========= BEFORE THIRD BATCH ==========");
CheckRpcSendOk(10);
diff --git a/test/cpp/interop/client.cc b/test/cpp/interop/client.cc
index ca8ee3d..3eb155e 100644
--- a/test/cpp/interop/client.cc
+++ b/test/cpp/interop/client.cc
@@ -31,6 +31,8 @@
#include "test/cpp/interop/interop_client.h"
#include "test/cpp/util/test_config.h"
+DEFINE_bool(use_alts, false,
+ "Whether to use alts. Enable alts will disable tls.");
DEFINE_bool(use_tls, false, "Whether to use tls.");
DEFINE_string(custom_credentials_type, "", "User provided credentials type.");
DEFINE_bool(use_test_ca, false, "False to use SSL roots for google");
diff --git a/test/cpp/interop/client_helper.cc b/test/cpp/interop/client_helper.cc
index 4041f95..29b5a1e 100644
--- a/test/cpp/interop/client_helper.cc
+++ b/test/cpp/interop/client_helper.cc
@@ -35,6 +35,7 @@
#include "test/cpp/util/create_test_channel.h"
#include "test/cpp/util/test_credentials_provider.h"
+DECLARE_bool(use_alts);
DECLARE_bool(use_tls);
DECLARE_string(custom_credentials_type);
DECLARE_bool(use_test_ca);
@@ -103,8 +104,10 @@
GPR_ASSERT(creds);
}
if (FLAGS_custom_credentials_type.empty()) {
+ transport_security security_type =
+ FLAGS_use_alts ? ALTS : (FLAGS_use_tls ? TLS : INSECURE);
return CreateTestChannel(host_port, FLAGS_server_host_override,
- FLAGS_use_tls, !FLAGS_use_test_ca, creds);
+ security_type, !FLAGS_use_test_ca, creds);
} else {
return CreateTestChannel(host_port, FLAGS_custom_credentials_type, creds);
}
diff --git a/test/cpp/interop/http2_client.cc b/test/cpp/interop/http2_client.cc
index 821815c..543f159 100644
--- a/test/cpp/interop/http2_client.cc
+++ b/test/cpp/interop/http2_client.cc
@@ -194,7 +194,7 @@
snprintf(host_port, host_port_buf_size, "%s:%d", FLAGS_server_host.c_str(),
FLAGS_server_port);
std::shared_ptr<grpc::Channel> channel =
- grpc::CreateTestChannel(host_port, false);
+ grpc::CreateTestChannel(host_port, grpc::testing::INSECURE);
GPR_ASSERT(channel->WaitForConnected(gpr_time_add(
gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_seconds(300, GPR_TIMESPAN))));
grpc::testing::Http2Client client(channel);
diff --git a/test/cpp/interop/interop_server.cc b/test/cpp/interop/interop_server.cc
index 5fa1a33..f55d624 100644
--- a/test/cpp/interop/interop_server.cc
+++ b/test/cpp/interop/interop_server.cc
@@ -38,6 +38,8 @@
#include "test/cpp/interop/server_helper.h"
#include "test/cpp/util/test_config.h"
+DEFINE_bool(use_alts, false,
+ "Whether to use alts. Enable alts will disable tls.");
DEFINE_bool(use_tls, false, "Whether to use tls.");
DEFINE_string(custom_credentials_type, "", "User provided credentials type.");
DEFINE_int32(port, 0, "Server port.");
@@ -316,12 +318,27 @@
void grpc::testing::interop::RunServer(
std::shared_ptr<ServerCredentials> creds) {
- RunServer(creds, FLAGS_port, nullptr);
+ RunServer(creds, FLAGS_port, nullptr, nullptr);
+}
+
+void grpc::testing::interop::RunServer(
+ std::shared_ptr<ServerCredentials> creds,
+ std::unique_ptr<std::vector<std::unique_ptr<ServerBuilderOption>>>
+ server_options) {
+ RunServer(creds, FLAGS_port, nullptr, std::move(server_options));
}
void grpc::testing::interop::RunServer(
std::shared_ptr<ServerCredentials> creds, const int port,
ServerStartedCondition* server_started_condition) {
+ RunServer(creds, port, server_started_condition, nullptr);
+}
+
+void grpc::testing::interop::RunServer(
+ std::shared_ptr<ServerCredentials> creds, const int port,
+ ServerStartedCondition* server_started_condition,
+ std::unique_ptr<std::vector<std::unique_ptr<ServerBuilderOption>>>
+ server_options) {
GPR_ASSERT(port != 0);
std::ostringstream server_address;
server_address << "0.0.0.0:" << port;
@@ -333,6 +350,11 @@
ServerBuilder builder;
builder.RegisterService(&service);
builder.AddListeningPort(server_address.str(), creds);
+ if (server_options != nullptr) {
+ for (size_t i = 0; i < server_options->size(); i++) {
+ builder.SetOption(std::move((*server_options)[i]));
+ }
+ }
if (FLAGS_max_send_message_size >= 0) {
builder.SetMaxSendMessageSize(FLAGS_max_send_message_size);
}
diff --git a/test/cpp/interop/reconnect_interop_client.cc b/test/cpp/interop/reconnect_interop_client.cc
index 9a451fa..8a071d4 100644
--- a/test/cpp/interop/reconnect_interop_client.cc
+++ b/test/cpp/interop/reconnect_interop_client.cc
@@ -44,9 +44,11 @@
using grpc::CreateTestChannel;
using grpc::Status;
using grpc::testing::Empty;
+using grpc::testing::INSECURE;
using grpc::testing::ReconnectInfo;
using grpc::testing::ReconnectParams;
using grpc::testing::ReconnectService;
+using grpc::testing::TLS;
int main(int argc, char** argv) {
grpc::testing::InitTest(&argc, &argv, true);
@@ -57,7 +59,7 @@
server_address << FLAGS_server_host << ':' << FLAGS_server_control_port;
std::unique_ptr<ReconnectService::Stub> control_stub(
ReconnectService::NewStub(
- CreateTestChannel(server_address.str(), false)));
+ CreateTestChannel(server_address.str(), INSECURE)));
ClientContext start_context;
ReconnectParams reconnect_params;
reconnect_params.set_max_reconnect_backoff_ms(FLAGS_max_reconnect_backoff_ms);
@@ -75,7 +77,7 @@
FLAGS_max_reconnect_backoff_ms);
}
std::shared_ptr<Channel> retry_channel =
- CreateTestChannel(server_address.str(), "foo.test.google.fr", true, false,
+ CreateTestChannel(server_address.str(), "foo.test.google.fr", TLS, false,
std::shared_ptr<CallCredentials>(), channel_args);
// About 13 retries.
diff --git a/test/cpp/interop/server_helper.cc b/test/cpp/interop/server_helper.cc
index 93ffd52..2194521 100644
--- a/test/cpp/interop/server_helper.cc
+++ b/test/cpp/interop/server_helper.cc
@@ -26,6 +26,7 @@
#include "src/core/lib/surface/call_test_only.h"
#include "test/cpp/util/test_credentials_provider.h"
+DECLARE_bool(use_alts);
DECLARE_bool(use_tls);
DECLARE_string(custom_credentials_type);
@@ -36,6 +37,8 @@
if (!FLAGS_custom_credentials_type.empty()) {
return GetCredentialsProvider()->GetServerCredentials(
FLAGS_custom_credentials_type);
+ } else if (FLAGS_use_alts) {
+ return GetCredentialsProvider()->GetServerCredentials(kAltsCredentialsType);
} else if (FLAGS_use_tls) {
return GetCredentialsProvider()->GetServerCredentials(kTlsCredentialsType);
} else {
diff --git a/test/cpp/interop/server_helper.h b/test/cpp/interop/server_helper.h
index 3004e7f..265874d 100644
--- a/test/cpp/interop/server_helper.h
+++ b/test/cpp/interop/server_helper.h
@@ -26,6 +26,8 @@
#include <grpc/impl/codegen/atm.h>
#include <grpcpp/security/server_credentials.h>
+#include <grpcpp/server.h>
+#include <grpcpp/server_builder.h>
#include <grpcpp/server_context.h>
namespace grpc {
@@ -72,6 +74,28 @@
void RunServer(std::shared_ptr<ServerCredentials> creds, int port,
ServerStartedCondition* server_started_condition);
+/// Run gRPC interop server.
+///
+/// \param creds The credentials associated with the server.
+/// \param server_options List of options to set when building the server.
+void RunServer(
+ std::shared_ptr<ServerCredentials> creds,
+ std::unique_ptr<std::vector<std::unique_ptr<ServerBuilderOption>>>
+ server_options);
+
+/// Run gRPC interop server.
+///
+/// \param creds The credentials associated with the server.
+/// \param port Port to use for the server.
+/// \param server_options List of options to set when building the server.
+/// \param server_started_condition (optional) Struct holding mutex, condition
+// variable, and condition used to notify when the server has started.
+void RunServer(
+ std::shared_ptr<ServerCredentials> creds, const int port,
+ ServerStartedCondition* server_started_condition,
+ std::unique_ptr<std::vector<std::unique_ptr<grpc::ServerBuilderOption>>>
+ server_options);
+
} // namespace interop
} // namespace testing
} // namespace grpc
diff --git a/test/cpp/interop/stress_test.cc b/test/cpp/interop/stress_test.cc
index 6e8134a..023e0c8 100644
--- a/test/cpp/interop/stress_test.cc
+++ b/test/cpp/interop/stress_test.cc
@@ -99,18 +99,24 @@
// Options from client.cc (for compatibility with interop test).
// TODO(sreek): Consolidate overlapping options
+DEFINE_bool(use_alts, false,
+ "Whether to use alts. Enable alts will disable tls.");
DEFINE_bool(use_tls, false, "Whether to use tls.");
DEFINE_bool(use_test_ca, false, "False to use SSL roots for google");
DEFINE_string(server_host_override, "foo.test.google.fr",
"Override the server host which is sent in HTTP header");
+using grpc::testing::ALTS;
+using grpc::testing::INSECURE;
using grpc::testing::MetricsService;
using grpc::testing::MetricsServiceImpl;
using grpc::testing::StressTestInteropClient;
+using grpc::testing::TLS;
using grpc::testing::TestCaseType;
using grpc::testing::UNKNOWN_TEST;
using grpc::testing::WeightedRandomTestSelector;
using grpc::testing::kTestCaseList;
+using grpc::testing::transport_security;
static int log_level = GPR_LOG_SEVERITY_DEBUG;
@@ -268,6 +274,8 @@
int thread_idx = 0;
int server_idx = -1;
char buffer[256];
+ transport_security security_type =
+ FLAGS_use_alts ? ALTS : (FLAGS_use_tls ? TLS : INSECURE);
for (auto it = server_addresses.begin(); it != server_addresses.end(); it++) {
++server_idx;
// Create channel(s) for each server
@@ -276,7 +284,7 @@
gpr_log(GPR_INFO, "Starting test with %s channel_idx=%d..", it->c_str(),
channel_idx);
std::shared_ptr<grpc::Channel> channel = grpc::CreateTestChannel(
- *it, FLAGS_server_host_override, FLAGS_use_tls, !FLAGS_use_test_ca);
+ *it, FLAGS_server_host_override, security_type, !FLAGS_use_test_ca);
// Create stub(s) for each channel
for (int stub_idx = 0; stub_idx < FLAGS_num_stubs_per_channel;
diff --git a/test/cpp/microbenchmarks/BUILD b/test/cpp/microbenchmarks/BUILD
index 67f7e44..5dcfd94 100644
--- a/test/cpp/microbenchmarks/BUILD
+++ b/test/cpp/microbenchmarks/BUILD
@@ -42,6 +42,7 @@
"//:grpc++_unsecure",
"//src/proto/grpc/testing:echo_proto",
"//test/core/util:grpc_test_util_unsecure",
+ "//test/cpp/util:test_config",
],
)
@@ -113,10 +114,7 @@
name = "bm_fullstack_trickle",
testonly = 1,
srcs = ["bm_fullstack_trickle.cc"],
- deps = [
- ":helpers",
- "//test/cpp/util:test_config",
- ],
+ deps = [":helpers"],
)
grpc_cc_library(
diff --git a/test/cpp/microbenchmarks/bm_arena.cc b/test/cpp/microbenchmarks/bm_arena.cc
index 69c8c1c..b97c954 100644
--- a/test/cpp/microbenchmarks/bm_arena.cc
+++ b/test/cpp/microbenchmarks/bm_arena.cc
@@ -18,9 +18,10 @@
/* Benchmark arenas */
+#include <benchmark/benchmark.h>
#include "src/core/lib/gpr/arena.h"
#include "test/cpp/microbenchmarks/helpers.h"
-#include "third_party/benchmark/include/benchmark/benchmark.h"
+#include "test/cpp/util/test_config.h"
static void BM_Arena_NoOp(benchmark::State& state) {
while (state.KeepRunning()) {
@@ -56,4 +57,15 @@
}
BENCHMARK(BM_Arena_Batch)->Ranges({{1, 64 * 1024}, {1, 64}, {1, 1024}});
-BENCHMARK_MAIN();
+// Some distros have RunSpecifiedBenchmarks under the benchmark namespace,
+// and others do not. This allows us to support both modes.
+namespace benchmark {
+void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); }
+} // namespace benchmark
+
+int main(int argc, char** argv) {
+ ::benchmark::Initialize(&argc, argv);
+ ::grpc::testing::InitTest(&argc, &argv, false);
+ benchmark::RunTheBenchmarksNamespaced();
+ return 0;
+}
diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc
index 85a9f5e..831b29c 100644
--- a/test/cpp/microbenchmarks/bm_call_create.cc
+++ b/test/cpp/microbenchmarks/bm_call_create.cc
@@ -46,6 +46,7 @@
#include "src/cpp/client/create_channel_internal.h"
#include "src/proto/grpc/testing/echo.grpc.pb.h"
#include "test/cpp/microbenchmarks/helpers.h"
+#include "test/cpp/util/test_config.h"
auto& force_library_initialization = Library::get();
@@ -813,4 +814,15 @@
}
BENCHMARK(BM_IsolatedCall_StreamingSend);
-BENCHMARK_MAIN();
+// Some distros have RunSpecifiedBenchmarks under the benchmark namespace,
+// and others do not. This allows us to support both modes.
+namespace benchmark {
+void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); }
+} // namespace benchmark
+
+int main(int argc, char** argv) {
+ ::benchmark::Initialize(&argc, argv);
+ ::grpc::testing::InitTest(&argc, &argv, false);
+ benchmark::RunTheBenchmarksNamespaced();
+ return 0;
+}
diff --git a/test/cpp/microbenchmarks/bm_chttp2_hpack.cc b/test/cpp/microbenchmarks/bm_chttp2_hpack.cc
index d0f3ec8..823c76f 100644
--- a/test/cpp/microbenchmarks/bm_chttp2_hpack.cc
+++ b/test/cpp/microbenchmarks/bm_chttp2_hpack.cc
@@ -33,6 +33,7 @@
#include "src/core/lib/transport/timeout_encoding.h"
#include "test/cpp/microbenchmarks/helpers.h"
+#include "test/cpp/util/test_config.h"
auto& force_library_initialization = Library::get();
@@ -855,4 +856,15 @@
} // namespace hpack_parser_fixtures
-BENCHMARK_MAIN();
+// Some distros have RunSpecifiedBenchmarks under the benchmark namespace,
+// and others do not. This allows us to support both modes.
+namespace benchmark {
+void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); }
+} // namespace benchmark
+
+int main(int argc, char** argv) {
+ ::benchmark::Initialize(&argc, argv);
+ ::grpc::testing::InitTest(&argc, &argv, false);
+ benchmark::RunTheBenchmarksNamespaced();
+ return 0;
+}
diff --git a/test/cpp/microbenchmarks/bm_chttp2_transport.cc b/test/cpp/microbenchmarks/bm_chttp2_transport.cc
index d00c79b..1e9bd27 100644
--- a/test/cpp/microbenchmarks/bm_chttp2_transport.cc
+++ b/test/cpp/microbenchmarks/bm_chttp2_transport.cc
@@ -18,6 +18,7 @@
/* Microbenchmarks around CHTTP2 transport operations */
+#include <benchmark/benchmark.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
@@ -33,7 +34,7 @@
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/transport/static_metadata.h"
#include "test/cpp/microbenchmarks/helpers.h"
-#include "third_party/benchmark/include/benchmark/benchmark.h"
+#include "test/cpp/util/test_config.h"
auto& force_library_initialization = Library::get();
@@ -638,4 +639,15 @@
}
BENCHMARK(BM_TransportStreamRecv)->Range(0, 128 * 1024 * 1024);
-BENCHMARK_MAIN();
+// Some distros have RunSpecifiedBenchmarks under the benchmark namespace,
+// and others do not. This allows us to support both modes.
+namespace benchmark {
+void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); }
+} // namespace benchmark
+
+int main(int argc, char** argv) {
+ ::benchmark::Initialize(&argc, argv);
+ ::grpc::testing::InitTest(&argc, &argv, false);
+ benchmark::RunTheBenchmarksNamespaced();
+ return 0;
+}
diff --git a/test/cpp/microbenchmarks/bm_closure.cc b/test/cpp/microbenchmarks/bm_closure.cc
index 6d88fae..8bdc3b9 100644
--- a/test/cpp/microbenchmarks/bm_closure.cc
+++ b/test/cpp/microbenchmarks/bm_closure.cc
@@ -28,6 +28,7 @@
#include "src/core/lib/iomgr/exec_ctx.h"
#include "test/cpp/microbenchmarks/helpers.h"
+#include "test/cpp/util/test_config.h"
auto& force_library_initialization = Library::get();
@@ -415,4 +416,15 @@
}
BENCHMARK(BM_ClosureReschedOnCombinerFinally);
-BENCHMARK_MAIN();
+// Some distros have RunSpecifiedBenchmarks under the benchmark namespace,
+// and others do not. This allows us to support both modes.
+namespace benchmark {
+void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); }
+} // namespace benchmark
+
+int main(int argc, char** argv) {
+ ::benchmark::Initialize(&argc, argv);
+ ::grpc::testing::InitTest(&argc, &argv, false);
+ benchmark::RunTheBenchmarksNamespaced();
+ return 0;
+}
diff --git a/test/cpp/microbenchmarks/bm_cq.cc b/test/cpp/microbenchmarks/bm_cq.cc
index 342a95e..a7cb939 100644
--- a/test/cpp/microbenchmarks/bm_cq.cc
+++ b/test/cpp/microbenchmarks/bm_cq.cc
@@ -25,6 +25,7 @@
#include <grpcpp/completion_queue.h>
#include <grpcpp/impl/grpc_library.h>
#include "test/cpp/microbenchmarks/helpers.h"
+#include "test/cpp/util/test_config.h"
#include "src/core/lib/surface/completion_queue.h"
@@ -148,4 +149,15 @@
} // namespace testing
} // namespace grpc
-BENCHMARK_MAIN();
+// Some distros have RunSpecifiedBenchmarks under the benchmark namespace,
+// and others do not. This allows us to support both modes.
+namespace benchmark {
+void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); }
+} // namespace benchmark
+
+int main(int argc, char** argv) {
+ ::benchmark::Initialize(&argc, argv);
+ ::grpc::testing::InitTest(&argc, &argv, false);
+ benchmark::RunTheBenchmarksNamespaced();
+ return 0;
+}
diff --git a/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc b/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc
index ec79b95..da095c3 100644
--- a/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc
+++ b/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc
@@ -24,6 +24,7 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include "test/cpp/microbenchmarks/helpers.h"
+#include "test/cpp/util/test_config.h"
#include "src/core/lib/iomgr/ev_posix.h"
#include "src/core/lib/iomgr/port.h"
@@ -164,4 +165,15 @@
} // namespace testing
} // namespace grpc
-BENCHMARK_MAIN();
+// Some distros have RunSpecifiedBenchmarks under the benchmark namespace,
+// and others do not. This allows us to support both modes.
+namespace benchmark {
+void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); }
+} // namespace benchmark
+
+int main(int argc, char** argv) {
+ ::benchmark::Initialize(&argc, argv);
+ ::grpc::testing::InitTest(&argc, &argv, false);
+ benchmark::RunTheBenchmarksNamespaced();
+ return 0;
+}
diff --git a/test/cpp/microbenchmarks/bm_error.cc b/test/cpp/microbenchmarks/bm_error.cc
index d12f475..ae557a5 100644
--- a/test/cpp/microbenchmarks/bm_error.cc
+++ b/test/cpp/microbenchmarks/bm_error.cc
@@ -25,6 +25,7 @@
#include "src/core/lib/transport/error_utils.h"
#include "test/cpp/microbenchmarks/helpers.h"
+#include "test/cpp/util/test_config.h"
auto& force_library_initialization = Library::get();
@@ -310,4 +311,15 @@
BENCHMARK_SUITE(ErrorWithHttpError);
BENCHMARK_SUITE(ErrorWithNestedGrpcStatus);
-BENCHMARK_MAIN();
+// Some distros have RunSpecifiedBenchmarks under the benchmark namespace,
+// and others do not. This allows us to support both modes.
+namespace benchmark {
+void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); }
+} // namespace benchmark
+
+int main(int argc, char** argv) {
+ ::benchmark::Initialize(&argc, argv);
+ ::grpc::testing::InitTest(&argc, &argv, false);
+ benchmark::RunTheBenchmarksNamespaced();
+ return 0;
+}
diff --git a/test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc b/test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc
index 655e032..34df77a 100644
--- a/test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc
+++ b/test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc
@@ -19,6 +19,7 @@
/* Benchmark gRPC end2end in various configurations */
#include "test/cpp/microbenchmarks/fullstack_streaming_ping_pong.h"
+#include "test/cpp/util/test_config.h"
namespace grpc {
namespace testing {
@@ -114,4 +115,15 @@
} // namespace testing
} // namespace grpc
-BENCHMARK_MAIN();
+// Some distros have RunSpecifiedBenchmarks under the benchmark namespace,
+// and others do not. This allows us to support both modes.
+namespace benchmark {
+void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); }
+} // namespace benchmark
+
+int main(int argc, char** argv) {
+ ::benchmark::Initialize(&argc, argv);
+ ::grpc::testing::InitTest(&argc, &argv, false);
+ benchmark::RunTheBenchmarksNamespaced();
+ return 0;
+}
diff --git a/test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc b/test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc
index c7ceacd..da98f3c 100644
--- a/test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc
+++ b/test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc
@@ -19,6 +19,7 @@
/* Benchmark gRPC end2end in various configurations */
#include "test/cpp/microbenchmarks/fullstack_streaming_pump.h"
+#include "test/cpp/util/test_config.h"
namespace grpc {
namespace testing {
@@ -64,4 +65,15 @@
} // namespace testing
} // namespace grpc
-BENCHMARK_MAIN();
+// Some distros have RunSpecifiedBenchmarks under the benchmark namespace,
+// and others do not. This allows us to support both modes.
+namespace benchmark {
+void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); }
+} // namespace benchmark
+
+int main(int argc, char** argv) {
+ ::benchmark::Initialize(&argc, argv);
+ ::grpc::testing::InitTest(&argc, &argv, false);
+ benchmark::RunTheBenchmarksNamespaced();
+ return 0;
+}
diff --git a/test/cpp/microbenchmarks/bm_fullstack_trickle.cc b/test/cpp/microbenchmarks/bm_fullstack_trickle.cc
index 3b21c4c..1af92d2 100644
--- a/test/cpp/microbenchmarks/bm_fullstack_trickle.cc
+++ b/test/cpp/microbenchmarks/bm_fullstack_trickle.cc
@@ -458,10 +458,16 @@
extern gpr_timespec (*gpr_now_impl)(gpr_clock_type clock_type);
+// Some distros have RunSpecifiedBenchmarks under the benchmark namespace,
+// and others do not. This allows us to support both modes.
+namespace benchmark {
+void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); }
+} // namespace benchmark
+
int main(int argc, char** argv) {
::benchmark::Initialize(&argc, argv);
::grpc::testing::InitTest(&argc, &argv, false);
grpc_timer_manager_set_threading(false);
gpr_now_impl = ::grpc::testing::fake_now;
- ::benchmark::RunSpecifiedBenchmarks();
+ benchmark::RunTheBenchmarksNamespaced();
}
diff --git a/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc b/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc
index fa41d11..5a7a8d5 100644
--- a/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc
+++ b/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc
@@ -19,6 +19,7 @@
/* Benchmark gRPC end2end in various configurations */
#include "test/cpp/microbenchmarks/fullstack_unary_ping_pong.h"
+#include "test/cpp/util/test_config.h"
namespace grpc {
namespace testing {
@@ -164,4 +165,15 @@
} // namespace testing
} // namespace grpc
-BENCHMARK_MAIN();
+// Some distros have RunSpecifiedBenchmarks under the benchmark namespace,
+// and others do not. This allows us to support both modes.
+namespace benchmark {
+void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); }
+} // namespace benchmark
+
+int main(int argc, char** argv) {
+ ::benchmark::Initialize(&argc, argv);
+ ::grpc::testing::InitTest(&argc, &argv, false);
+ benchmark::RunTheBenchmarksNamespaced();
+ return 0;
+}
diff --git a/test/cpp/microbenchmarks/bm_metadata.cc b/test/cpp/microbenchmarks/bm_metadata.cc
index f1e7890..553b33c 100644
--- a/test/cpp/microbenchmarks/bm_metadata.cc
+++ b/test/cpp/microbenchmarks/bm_metadata.cc
@@ -25,6 +25,7 @@
#include "src/core/lib/transport/static_metadata.h"
#include "test/cpp/microbenchmarks/helpers.h"
+#include "test/cpp/util/test_config.h"
auto& force_library_initialization = Library::get();
@@ -290,4 +291,15 @@
}
BENCHMARK(BM_MetadataRefUnrefStatic);
-BENCHMARK_MAIN();
+// Some distros have RunSpecifiedBenchmarks under the benchmark namespace,
+// and others do not. This allows us to support both modes.
+namespace benchmark {
+void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); }
+} // namespace benchmark
+
+int main(int argc, char** argv) {
+ ::benchmark::Initialize(&argc, argv);
+ ::grpc::testing::InitTest(&argc, &argv, false);
+ benchmark::RunTheBenchmarksNamespaced();
+ return 0;
+}
diff --git a/test/cpp/microbenchmarks/bm_pollset.cc b/test/cpp/microbenchmarks/bm_pollset.cc
index f49f667..bcb68ff 100644
--- a/test/cpp/microbenchmarks/bm_pollset.cc
+++ b/test/cpp/microbenchmarks/bm_pollset.cc
@@ -18,6 +18,7 @@
/* Test out pollset latencies */
+#include <benchmark/benchmark.h>
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
@@ -29,7 +30,7 @@
#include "src/core/lib/iomgr/wakeup_fd_posix.h"
#include "test/cpp/microbenchmarks/helpers.h"
-#include "third_party/benchmark/include/benchmark/benchmark.h"
+#include "test/cpp/util/test_config.h"
#include <string.h>
@@ -256,4 +257,15 @@
}
BENCHMARK(BM_SingleThreadPollOneFd);
-BENCHMARK_MAIN();
+// Some distros have RunSpecifiedBenchmarks under the benchmark namespace,
+// and others do not. This allows us to support both modes.
+namespace benchmark {
+void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); }
+} // namespace benchmark
+
+int main(int argc, char** argv) {
+ ::benchmark::Initialize(&argc, argv);
+ ::grpc::testing::InitTest(&argc, &argv, false);
+ benchmark::RunTheBenchmarksNamespaced();
+ return 0;
+}
diff --git a/test/cpp/microbenchmarks/helpers.cc b/test/cpp/microbenchmarks/helpers.cc
index e4a31f5..e4ba37e 100644
--- a/test/cpp/microbenchmarks/helpers.cc
+++ b/test/cpp/microbenchmarks/helpers.cc
@@ -48,16 +48,10 @@
static_cast<double>(state.iterations()));
}
for (int i = 0; i < GRPC_STATS_HISTOGRAM_COUNT; i++) {
- std::ostringstream median_ss;
- median_ss << grpc_stats_histogram_name[i] << "-median";
- state.counters[median_ss.str()] =
- benchmark::Counter(grpc_stats_histo_percentile(
- &stats, static_cast<grpc_stats_histograms>(i), 50.0));
- std::ostringstream tail_ss;
- tail_ss << grpc_stats_histogram_name[i] << "-99p";
- state.counters[tail_ss.str()] =
- benchmark::Counter(grpc_stats_histo_percentile(
- &stats, static_cast<grpc_stats_histograms>(i), 99.0));
+ out << " " << grpc_stats_histogram_name[i] << "-median:"
+ << grpc_stats_histo_percentile(&stats, (grpc_stats_histograms)i, 50.0)
+ << " " << grpc_stats_histogram_name[i] << "-99p:"
+ << grpc_stats_histo_percentile(&stats, (grpc_stats_histograms)i, 99.0);
}
#ifdef GPR_LOW_LEVEL_COUNTERS
grpc_memory_counters counters_at_end = grpc_memory_counters_snapshot();
diff --git a/test/cpp/naming/BUILD b/test/cpp/naming/BUILD
index 54b53d2..fa0b216 100644
--- a/test/cpp/naming/BUILD
+++ b/test/cpp/naming/BUILD
@@ -22,16 +22,17 @@
licenses(["notice"]) # Apache v2
-load("//bazel:grpc_build_system.bzl", "grpc_sh_binary", "grpc_py_binary")
+load("//bazel:grpc_build_system.bzl", "grpc_py_binary")
load(":generate_resolver_component_tests.bzl", "generate_resolver_component_tests")
# Meant to be invoked only through the top-level shell script driver.
-grpc_sh_binary(
+grpc_py_binary(
name = "resolver_component_tests_runner",
srcs = [
- "resolver_component_tests_runner.sh",
+ "resolver_component_tests_runner.py",
],
+ testonly = True,
)
generate_resolver_component_tests()
diff --git a/test/cpp/naming/address_sorting_test.cc b/test/cpp/naming/address_sorting_test.cc
index df93ff6..a92e9e3 100644
--- a/test/cpp/naming/address_sorting_test.cc
+++ b/test/cpp/naming/address_sorting_test.cc
@@ -298,6 +298,29 @@
});
}
+/* Flip the input on the test above to reorder the sort function's
+ * comparator's inputs. */
+TEST(AddressSortingTest, TestUsesLabelFromDefaultTableInputFlipped) {
+ bool ipv4_supported = true;
+ bool ipv6_supported = true;
+ OverrideAddressSortingSourceAddrFactory(
+ ipv4_supported, ipv6_supported,
+ {
+ {"[2002::5001]:443", {"[2001::5002]:0", AF_INET6}},
+ {"[2001::5001]:443",
+ {"[2001::5002]:0", AF_INET6}}, // matching labels
+ });
+ grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ {"[2001::5001]:443", AF_INET6},
+ {"[2002::5001]:443", AF_INET6},
+ });
+ grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs);
+ VerifyLbAddrOutputs(lb_addrs, {
+ "[2001::5001]:443",
+ "[2002::5001]:443",
+ });
+}
+
/* Tests for rule 6 */
TEST(AddressSortingTest,
@@ -722,16 +745,24 @@
}
int main(int argc, char** argv) {
- const char* resolver = gpr_getenv("GRPC_DNS_RESOLVER");
+ char* resolver = gpr_getenv("GRPC_DNS_RESOLVER");
if (resolver == nullptr || strlen(resolver) == 0) {
gpr_setenv("GRPC_DNS_RESOLVER", "ares");
} else if (strcmp("ares", resolver)) {
gpr_log(GPR_INFO, "GRPC_DNS_RESOLVER != ares: %s.", resolver);
}
+ gpr_free(resolver);
grpc_test_init(argc, argv);
::testing::InitGoogleTest(&argc, argv);
grpc_init();
auto result = RUN_ALL_TESTS();
grpc_shutdown();
+ // Test sequential and nested inits and shutdowns.
+ grpc_init();
+ grpc_init();
+ grpc_shutdown();
+ grpc_shutdown();
+ grpc_init();
+ grpc_shutdown();
return result;
}
diff --git a/test/cpp/naming/generate_resolver_component_tests.bzl b/test/cpp/naming/generate_resolver_component_tests.bzl
index ebc1679..5e9aa63 100755
--- a/test/cpp/naming/generate_resolver_component_tests.bzl
+++ b/test/cpp/naming/generate_resolver_component_tests.bzl
@@ -13,7 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-load("//bazel:grpc_build_system.bzl", "grpc_sh_binary", "grpc_cc_test", "grpc_cc_binary")
+load("//bazel:grpc_build_system.bzl", "grpc_cc_test", "grpc_cc_binary")
def generate_resolver_component_tests():
for unsecure_build_config_suffix in ['_unsecure', '']:
diff --git a/test/cpp/naming/resolver_component_test.cc b/test/cpp/naming/resolver_component_test.cc
index bfdcd96..f4be064 100644
--- a/test/cpp/naming/resolver_component_test.cc
+++ b/test/cpp/naming/resolver_component_test.cc
@@ -65,11 +65,6 @@
"List of expected backend or balancer addresses in the form "
"'<ip0:port0>,<is_balancer0>;<ip1:port1>,<is_balancer1>;...'. "
"'is_balancer' should be bool, i.e. true or false.");
-DEFINE_bool(allow_extra_addrs, false,
- "Permit extra resolved addresses in the final list of "
- "resolved addresses. This is useful in certain integration "
- "test environments in which DNS responses are not fully "
- "deterministic.");
DEFINE_string(expected_chosen_service_config, "",
"Expected service config json string that gets chosen (no "
"whitespace). Empty for none.");
@@ -245,11 +240,9 @@
GPR_ASSERT(channel_arg->type == GRPC_ARG_POINTER);
grpc_lb_addresses* addresses =
(grpc_lb_addresses*)channel_arg->value.pointer.p;
- gpr_log(GPR_INFO,
- "num addrs found: %" PRIdPTR ". expected %" PRIdPTR
- ". Allow extra addresses:%d.",
- addresses->num_addresses, args->expected_addrs.size(),
- FLAGS_allow_extra_addrs);
+ gpr_log(GPR_INFO, "num addrs found: %" PRIdPTR ". expected %" PRIdPTR,
+ addresses->num_addresses, args->expected_addrs.size());
+ GPR_ASSERT(addresses->num_addresses == args->expected_addrs.size());
std::vector<GrpcLBAddress> found_lb_addrs;
for (size_t i = 0; i < addresses->num_addresses; i++) {
grpc_lb_address addr = addresses->addresses[i];
@@ -261,20 +254,13 @@
gpr_free(str);
}
if (args->expected_addrs.size() != found_lb_addrs.size()) {
- // Permit extra resolved addresses if "--allow_extra_addrs" was set.
- if (!(FLAGS_allow_extra_addrs &&
- found_lb_addrs.size() > args->expected_addrs.size())) {
- gpr_log(GPR_DEBUG,
- "found lb addrs size is: %" PRIdPTR
- ". expected addrs size is %" PRIdPTR ". --allow_extra_addrs=%d.",
- found_lb_addrs.size(), args->expected_addrs.size(),
- FLAGS_allow_extra_addrs);
- abort();
- }
+ gpr_log(GPR_DEBUG,
+ "found lb addrs size is: %" PRIdPTR
+ ". expected addrs size is %" PRIdPTR,
+ found_lb_addrs.size(), args->expected_addrs.size());
+ abort();
}
- for (size_t i = 0; i < args->expected_addrs.size(); i++) {
- EXPECT_THAT(found_lb_addrs, ::testing::Contains(args->expected_addrs[i]));
- }
+ EXPECT_THAT(args->expected_addrs, UnorderedElementsAreArray(found_lb_addrs));
CheckServiceConfigResultLocked(channel_args, args);
if (args->expected_service_config_string == "") {
CheckLBPolicyResultLocked(channel_args, args);
diff --git a/test/cpp/naming/resolver_component_tests_runner.py b/test/cpp/naming/resolver_component_tests_runner.py
new file mode 100755
index 0000000..69386eb
--- /dev/null
+++ b/test/cpp/naming/resolver_component_tests_runner.py
@@ -0,0 +1,275 @@
+#!/usr/bin/env python
+# 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.
+
+# This file is auto-generated
+
+import argparse
+import sys
+import subprocess
+import tempfile
+import os
+import time
+import signal
+
+
+argp = argparse.ArgumentParser(description='Run c-ares resolver tests')
+argp.add_argument('--test_bin_path', default=None, type=str,
+ help='Path to gtest test binary to invoke.')
+argp.add_argument('--dns_server_bin_path', default=None, type=str,
+ help='Path to local DNS server python script.')
+argp.add_argument('--records_config_path', default=None, type=str,
+ help=('Path to DNS records yaml file that '
+ 'specifies records for the DNS sever. '))
+argp.add_argument('--dns_server_port', default=None, type=int,
+ help=('Port that local DNS server is listening on.'))
+argp.add_argument('--dns_resolver_bin_path', default=None, type=str,
+ help=('Path to the DNS health check utility.'))
+argp.add_argument('--tcp_connect_bin_path', default=None, type=str,
+ help=('Path to the TCP health check utility.'))
+args = argp.parse_args()
+
+def test_runner_log(msg):
+ sys.stderr.write('\n%s: %s\n' % (__file__, msg))
+
+cur_resolver = os.environ.get('GRPC_DNS_RESOLVER')
+if cur_resolver and cur_resolver != 'ares':
+ test_runner_log(('WARNING: cur resolver set to %s. This set of tests '
+ 'needs to use GRPC_DNS_RESOLVER=ares.'))
+ test_runner_log('Exit 1 without running tests.')
+ sys.exit(1)
+os.environ.update({'GRPC_DNS_RESOLVER': 'ares'})
+
+def wait_until_dns_server_is_up(args,
+ dns_server_subprocess,
+ dns_server_subprocess_output):
+ for i in range(0, 30):
+ test_runner_log('Health check: attempt to connect to DNS server over TCP.')
+ tcp_connect_subprocess = subprocess.Popen([
+ args.tcp_connect_bin_path,
+ '--server_host', '127.0.0.1',
+ '--server_port', str(args.dns_server_port),
+ '--timeout', str(1)])
+ tcp_connect_subprocess.communicate()
+ if tcp_connect_subprocess.returncode == 0:
+ test_runner_log(('Health check: attempt to make an A-record '
+ 'query to DNS server.'))
+ dns_resolver_subprocess = subprocess.Popen([
+ args.dns_resolver_bin_path,
+ '--qname', 'health-check-local-dns-server-is-alive.resolver-tests.grpctestingexp',
+ '--server_host', '127.0.0.1',
+ '--server_port', str(args.dns_server_port)],
+ stdout=subprocess.PIPE)
+ dns_resolver_stdout, _ = dns_resolver_subprocess.communicate()
+ if dns_resolver_subprocess.returncode == 0:
+ if '123.123.123.123' in dns_resolver_stdout:
+ test_runner_log(('DNS server is up! '
+ 'Successfully reached it over UDP and TCP.'))
+ return
+ time.sleep(0.1)
+ dns_server_subprocess.kill()
+ dns_server_subprocess.wait()
+ test_runner_log(('Failed to reach DNS server over TCP and/or UDP. '
+ 'Exitting without running tests.'))
+ test_runner_log('======= DNS server stdout '
+ '(merged stdout and stderr) =============')
+ with open(dns_server_subprocess_output, 'r') as l:
+ test_runner_log(l.read())
+ test_runner_log('======= end DNS server output=========')
+ sys.exit(1)
+
+dns_server_subprocess_output = tempfile.mktemp()
+with open(dns_server_subprocess_output, 'w') as l:
+ dns_server_subprocess = subprocess.Popen([
+ args.dns_server_bin_path,
+ '--port', str(args.dns_server_port),
+ '--records_config_path', args.records_config_path],
+ stdin=subprocess.PIPE,
+ stdout=l,
+ stderr=l)
+
+def _quit_on_signal(signum, _frame):
+ test_runner_log('Received signal: %d' % signum)
+ dns_server_subprocess.kill()
+ dns_server_subprocess.wait()
+ sys.exit(1)
+
+signal.signal(signal.SIGINT, _quit_on_signal)
+signal.signal(signal.SIGTERM, _quit_on_signal)
+wait_until_dns_server_is_up(args,
+ dns_server_subprocess,
+ dns_server_subprocess_output)
+num_test_failures = 0
+
+test_runner_log('Run test with target: %s' % 'srv-ipv4-single-target.resolver-tests-version-4.grpctestingexp.')
+current_test_subprocess = subprocess.Popen([
+ args.test_bin_path,
+ '--target_name', 'srv-ipv4-single-target.resolver-tests-version-4.grpctestingexp.',
+ '--expected_addrs', '1.2.3.4:1234,True',
+ '--expected_chosen_service_config', '',
+ '--expected_lb_policy', '',
+ '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+current_test_subprocess.communicate()
+if current_test_subprocess.returncode != 0:
+ num_test_failures += 1
+
+test_runner_log('Run test with target: %s' % 'srv-ipv4-multi-target.resolver-tests-version-4.grpctestingexp.')
+current_test_subprocess = subprocess.Popen([
+ args.test_bin_path,
+ '--target_name', 'srv-ipv4-multi-target.resolver-tests-version-4.grpctestingexp.',
+ '--expected_addrs', '1.2.3.5:1234,True;1.2.3.6:1234,True;1.2.3.7:1234,True',
+ '--expected_chosen_service_config', '',
+ '--expected_lb_policy', '',
+ '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+current_test_subprocess.communicate()
+if current_test_subprocess.returncode != 0:
+ num_test_failures += 1
+
+test_runner_log('Run test with target: %s' % 'srv-ipv6-single-target.resolver-tests-version-4.grpctestingexp.')
+current_test_subprocess = subprocess.Popen([
+ args.test_bin_path,
+ '--target_name', 'srv-ipv6-single-target.resolver-tests-version-4.grpctestingexp.',
+ '--expected_addrs', '[2607:f8b0:400a:801::1001]:1234,True',
+ '--expected_chosen_service_config', '',
+ '--expected_lb_policy', '',
+ '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+current_test_subprocess.communicate()
+if current_test_subprocess.returncode != 0:
+ num_test_failures += 1
+
+test_runner_log('Run test with target: %s' % 'srv-ipv6-multi-target.resolver-tests-version-4.grpctestingexp.')
+current_test_subprocess = subprocess.Popen([
+ args.test_bin_path,
+ '--target_name', 'srv-ipv6-multi-target.resolver-tests-version-4.grpctestingexp.',
+ '--expected_addrs', '[2607:f8b0:400a:801::1002]:1234,True;[2607:f8b0:400a:801::1003]:1234,True;[2607:f8b0:400a:801::1004]:1234,True',
+ '--expected_chosen_service_config', '',
+ '--expected_lb_policy', '',
+ '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+current_test_subprocess.communicate()
+if current_test_subprocess.returncode != 0:
+ num_test_failures += 1
+
+test_runner_log('Run test with target: %s' % 'srv-ipv4-simple-service-config.resolver-tests-version-4.grpctestingexp.')
+current_test_subprocess = subprocess.Popen([
+ args.test_bin_path,
+ '--target_name', 'srv-ipv4-simple-service-config.resolver-tests-version-4.grpctestingexp.',
+ '--expected_addrs', '1.2.3.4:1234,True',
+ '--expected_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService","waitForReady":true}]}]}',
+ '--expected_lb_policy', 'round_robin',
+ '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+current_test_subprocess.communicate()
+if current_test_subprocess.returncode != 0:
+ num_test_failures += 1
+
+test_runner_log('Run test with target: %s' % 'ipv4-no-srv-simple-service-config.resolver-tests-version-4.grpctestingexp.')
+current_test_subprocess = subprocess.Popen([
+ args.test_bin_path,
+ '--target_name', 'ipv4-no-srv-simple-service-config.resolver-tests-version-4.grpctestingexp.',
+ '--expected_addrs', '1.2.3.4:443,False',
+ '--expected_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"NoSrvSimpleService","waitForReady":true}]}]}',
+ '--expected_lb_policy', 'round_robin',
+ '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+current_test_subprocess.communicate()
+if current_test_subprocess.returncode != 0:
+ num_test_failures += 1
+
+test_runner_log('Run test with target: %s' % 'ipv4-no-config-for-cpp.resolver-tests-version-4.grpctestingexp.')
+current_test_subprocess = subprocess.Popen([
+ args.test_bin_path,
+ '--target_name', 'ipv4-no-config-for-cpp.resolver-tests-version-4.grpctestingexp.',
+ '--expected_addrs', '1.2.3.4:443,False',
+ '--expected_chosen_service_config', '',
+ '--expected_lb_policy', '',
+ '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+current_test_subprocess.communicate()
+if current_test_subprocess.returncode != 0:
+ num_test_failures += 1
+
+test_runner_log('Run test with target: %s' % 'ipv4-cpp-config-has-zero-percentage.resolver-tests-version-4.grpctestingexp.')
+current_test_subprocess = subprocess.Popen([
+ args.test_bin_path,
+ '--target_name', 'ipv4-cpp-config-has-zero-percentage.resolver-tests-version-4.grpctestingexp.',
+ '--expected_addrs', '1.2.3.4:443,False',
+ '--expected_chosen_service_config', '',
+ '--expected_lb_policy', '',
+ '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+current_test_subprocess.communicate()
+if current_test_subprocess.returncode != 0:
+ num_test_failures += 1
+
+test_runner_log('Run test with target: %s' % 'ipv4-second-language-is-cpp.resolver-tests-version-4.grpctestingexp.')
+current_test_subprocess = subprocess.Popen([
+ args.test_bin_path,
+ '--target_name', 'ipv4-second-language-is-cpp.resolver-tests-version-4.grpctestingexp.',
+ '--expected_addrs', '1.2.3.4:443,False',
+ '--expected_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"CppService","waitForReady":true}]}]}',
+ '--expected_lb_policy', 'round_robin',
+ '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+current_test_subprocess.communicate()
+if current_test_subprocess.returncode != 0:
+ num_test_failures += 1
+
+test_runner_log('Run test with target: %s' % 'ipv4-config-with-percentages.resolver-tests-version-4.grpctestingexp.')
+current_test_subprocess = subprocess.Popen([
+ args.test_bin_path,
+ '--target_name', 'ipv4-config-with-percentages.resolver-tests-version-4.grpctestingexp.',
+ '--expected_addrs', '1.2.3.4:443,False',
+ '--expected_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"AlwaysPickedService","waitForReady":true}]}]}',
+ '--expected_lb_policy', 'round_robin',
+ '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+current_test_subprocess.communicate()
+if current_test_subprocess.returncode != 0:
+ num_test_failures += 1
+
+test_runner_log('Run test with target: %s' % 'srv-ipv4-target-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp.')
+current_test_subprocess = subprocess.Popen([
+ args.test_bin_path,
+ '--target_name', 'srv-ipv4-target-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp.',
+ '--expected_addrs', '1.2.3.4:1234,True;1.2.3.4:443,False',
+ '--expected_chosen_service_config', '',
+ '--expected_lb_policy', '',
+ '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+current_test_subprocess.communicate()
+if current_test_subprocess.returncode != 0:
+ num_test_failures += 1
+
+test_runner_log('Run test with target: %s' % 'srv-ipv6-target-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp.')
+current_test_subprocess = subprocess.Popen([
+ args.test_bin_path,
+ '--target_name', 'srv-ipv6-target-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp.',
+ '--expected_addrs', '[2607:f8b0:400a:801::1002]:1234,True;[2607:f8b0:400a:801::1002]:443,False',
+ '--expected_chosen_service_config', '',
+ '--expected_lb_policy', '',
+ '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+current_test_subprocess.communicate()
+if current_test_subprocess.returncode != 0:
+ num_test_failures += 1
+
+test_runner_log('Run test with target: %s' % 'ipv4-config-causing-fallback-to-tcp.resolver-tests-version-4.grpctestingexp.')
+current_test_subprocess = subprocess.Popen([
+ args.test_bin_path,
+ '--target_name', 'ipv4-config-causing-fallback-to-tcp.resolver-tests-version-4.grpctestingexp.',
+ '--expected_addrs', '1.2.3.4:443,False',
+ '--expected_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwo","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooThree","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooFour","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooFive","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooSix","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooSeven","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooEight","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooNine","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTen","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooEleven","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]}]}',
+ '--expected_lb_policy', '',
+ '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+current_test_subprocess.communicate()
+if current_test_subprocess.returncode != 0:
+ num_test_failures += 1
+
+test_runner_log('now kill DNS server')
+dns_server_subprocess.kill()
+dns_server_subprocess.wait()
+test_runner_log('%d tests failed.' % num_test_failures)
+sys.exit(num_test_failures)
diff --git a/test/cpp/naming/resolver_component_tests_runner.sh b/test/cpp/naming/resolver_component_tests_runner.sh
deleted file mode 100755
index 18b56ab..0000000
--- a/test/cpp/naming/resolver_component_tests_runner.sh
+++ /dev/null
@@ -1,183 +0,0 @@
-#!/bin/bash
-# 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.
-
-# This file is auto-generated
-
-set -ex
-
-# all command args required in this set order
-FLAGS_test_bin_path=$(echo "$1" | grep '\--test_bin_path=' | sed 's/^--test_bin_path=//')
-FLAGS_dns_server_bin_path=$(echo "$2" | grep '\--dns_server_bin_path=' | sed 's/^--dns_server_bin_path=//')
-FLAGS_records_config_path=$(echo "$3" | grep '\--records_config_path=' | sed 's/^--records_config_path=//')
-FLAGS_dns_server_port=$(echo "$4" | grep '\--dns_server_port=' | sed 's/^--dns_server_port=//')
-FLAGS_dns_resolver_bin_path=$(echo "$5" | grep '\--dns_resolver_bin_path=' | sed 's/^--dns_resolver_bin_path=//')
-FLAGS_tcp_connect_bin_path=$(echo "$6" | grep '\--tcp_connect_bin_path=' | sed 's/^--tcp_connect_bin_path=//')
-
-for cmd_arg in "$FLAGS_test_bin_path" "$FLAGS_dns_server_bin_path" "$FLAGS_records_config_path" "$FLAGS_dns_server_port" "$FLAGS_dns_resolver_bin_path" "$FLAGS_tcp_connect_bin_path"; do
- if [[ "$cmd_arg" == "" ]]; then
- echo "Missing a CMD arg" && exit 1
- fi
-done
-
-if [[ "$GRPC_DNS_RESOLVER" != "" && "$GRPC_DNS_RESOLVER" != ares ]]; then
- echo "This test only works under GRPC_DNS_RESOLVER=ares. Have GRPC_DNS_RESOLVER=$GRPC_DNS_RESOLVER" && exit 1
-fi
-export GRPC_DNS_RESOLVER=ares
-
-"$FLAGS_dns_server_bin_path" --records_config_path="$FLAGS_records_config_path" --port="$FLAGS_dns_server_port" > /dev/null 2>&1 &
-DNS_SERVER_PID=$!
-echo "Local DNS server started. PID: $DNS_SERVER_PID"
-
-# Health check local DNS server TCP and UDP ports
-for ((i=0;i<30;i++));
-do
- echo "Retry health-check local DNS server by attempting a DNS query and TCP handshake"
- RETRY=0
- $FLAGS_dns_resolver_bin_path -s 127.0.0.1 -p "$FLAGS_dns_server_port" -n health-check-local-dns-server-is-alive.resolver-tests.grpctestingexp. -t 1 | grep '123.123.123.123' || RETRY=1
- $FLAGS_tcp_connect_bin_path -s 127.0.0.1 -p "$FLAGS_dns_server_port" -t 1 || RETRY=1
- if [[ "$RETRY" == 0 ]]; then
- break
- fi;
- sleep 0.1
-done
-
-if [[ $RETRY == 1 ]]; then
- echo "FAILED TO START LOCAL DNS SERVER"
- kill -SIGTERM "$DNS_SERVER_PID"
- wait
- exit 1
-fi
-
-function terminate_all {
- echo "Received signal. Terminating $! and $DNS_SERVER_PID"
- kill -SIGTERM "$!" || true
- kill -SIGTERM "$DNS_SERVER_PID" || true
- wait
- exit 1
-}
-
-trap terminate_all SIGTERM SIGINT
-
-EXIT_CODE=0
-# TODO: this test should check for GCE residency and skip tests using _grpclb._tcp.* SRV records once GCE residency checks are made
-# in the resolver.
-
-$FLAGS_test_bin_path \
- --target_name='srv-ipv4-single-target.resolver-tests-version-4.grpctestingexp.' \
- --expected_addrs='1.2.3.4:1234,True' \
- --expected_chosen_service_config='' \
- --expected_lb_policy='' \
- --local_dns_server_address="127.0.0.1:$FLAGS_dns_server_port" &
-wait "$!" || EXIT_CODE=1
-
-$FLAGS_test_bin_path \
- --target_name='srv-ipv4-multi-target.resolver-tests-version-4.grpctestingexp.' \
- --expected_addrs='1.2.3.5:1234,True;1.2.3.6:1234,True;1.2.3.7:1234,True' \
- --expected_chosen_service_config='' \
- --expected_lb_policy='' \
- --local_dns_server_address="127.0.0.1:$FLAGS_dns_server_port" &
-wait "$!" || EXIT_CODE=1
-
-$FLAGS_test_bin_path \
- --target_name='srv-ipv6-single-target.resolver-tests-version-4.grpctestingexp.' \
- --expected_addrs='[2607:f8b0:400a:801::1001]:1234,True' \
- --expected_chosen_service_config='' \
- --expected_lb_policy='' \
- --local_dns_server_address="127.0.0.1:$FLAGS_dns_server_port" &
-wait "$!" || EXIT_CODE=1
-
-$FLAGS_test_bin_path \
- --target_name='srv-ipv6-multi-target.resolver-tests-version-4.grpctestingexp.' \
- --expected_addrs='[2607:f8b0:400a:801::1002]:1234,True;[2607:f8b0:400a:801::1003]:1234,True;[2607:f8b0:400a:801::1004]:1234,True' \
- --expected_chosen_service_config='' \
- --expected_lb_policy='' \
- --local_dns_server_address="127.0.0.1:$FLAGS_dns_server_port" &
-wait "$!" || EXIT_CODE=1
-
-$FLAGS_test_bin_path \
- --target_name='srv-ipv4-simple-service-config.resolver-tests-version-4.grpctestingexp.' \
- --expected_addrs='1.2.3.4:1234,True' \
- --expected_chosen_service_config='{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService","waitForReady":true}]}]}' \
- --expected_lb_policy='round_robin' \
- --local_dns_server_address="127.0.0.1:$FLAGS_dns_server_port" &
-wait "$!" || EXIT_CODE=1
-
-$FLAGS_test_bin_path \
- --target_name='ipv4-no-srv-simple-service-config.resolver-tests-version-4.grpctestingexp.' \
- --expected_addrs='1.2.3.4:443,False' \
- --expected_chosen_service_config='{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"NoSrvSimpleService","waitForReady":true}]}]}' \
- --expected_lb_policy='round_robin' \
- --local_dns_server_address="127.0.0.1:$FLAGS_dns_server_port" &
-wait "$!" || EXIT_CODE=1
-
-$FLAGS_test_bin_path \
- --target_name='ipv4-no-config-for-cpp.resolver-tests-version-4.grpctestingexp.' \
- --expected_addrs='1.2.3.4:443,False' \
- --expected_chosen_service_config='' \
- --expected_lb_policy='' \
- --local_dns_server_address="127.0.0.1:$FLAGS_dns_server_port" &
-wait "$!" || EXIT_CODE=1
-
-$FLAGS_test_bin_path \
- --target_name='ipv4-cpp-config-has-zero-percentage.resolver-tests-version-4.grpctestingexp.' \
- --expected_addrs='1.2.3.4:443,False' \
- --expected_chosen_service_config='' \
- --expected_lb_policy='' \
- --local_dns_server_address="127.0.0.1:$FLAGS_dns_server_port" &
-wait "$!" || EXIT_CODE=1
-
-$FLAGS_test_bin_path \
- --target_name='ipv4-second-language-is-cpp.resolver-tests-version-4.grpctestingexp.' \
- --expected_addrs='1.2.3.4:443,False' \
- --expected_chosen_service_config='{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"CppService","waitForReady":true}]}]}' \
- --expected_lb_policy='round_robin' \
- --local_dns_server_address="127.0.0.1:$FLAGS_dns_server_port" &
-wait "$!" || EXIT_CODE=1
-
-$FLAGS_test_bin_path \
- --target_name='ipv4-config-with-percentages.resolver-tests-version-4.grpctestingexp.' \
- --expected_addrs='1.2.3.4:443,False' \
- --expected_chosen_service_config='{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"AlwaysPickedService","waitForReady":true}]}]}' \
- --expected_lb_policy='round_robin' \
- --local_dns_server_address="127.0.0.1:$FLAGS_dns_server_port" &
-wait "$!" || EXIT_CODE=1
-
-$FLAGS_test_bin_path \
- --target_name='srv-ipv4-target-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp.' \
- --expected_addrs='1.2.3.4:1234,True;1.2.3.4:443,False' \
- --expected_chosen_service_config='' \
- --expected_lb_policy='' \
- --local_dns_server_address="127.0.0.1:$FLAGS_dns_server_port" &
-wait "$!" || EXIT_CODE=1
-
-$FLAGS_test_bin_path \
- --target_name='srv-ipv6-target-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp.' \
- --expected_addrs='[2607:f8b0:400a:801::1002]:1234,True;[2607:f8b0:400a:801::1002]:443,False' \
- --expected_chosen_service_config='' \
- --expected_lb_policy='' \
- --local_dns_server_address="127.0.0.1:$FLAGS_dns_server_port" &
-wait "$!" || EXIT_CODE=1
-
-$FLAGS_test_bin_path \
- --target_name='ipv4-config-causing-fallback-to-tcp.resolver-tests-version-4.grpctestingexp.' \
- --expected_addrs='1.2.3.4:443,False' \
- --expected_chosen_service_config='{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwo","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooThree","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooFour","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooFive","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooSix","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooSeven","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooEight","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooNine","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTen","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooEleven","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]}]}' \
- --expected_lb_policy='' \
- --local_dns_server_address="127.0.0.1:$FLAGS_dns_server_port" &
-wait "$!" || EXIT_CODE=1
-
-kill -SIGTERM "$DNS_SERVER_PID" || true
-wait
-exit $EXIT_CODE
diff --git a/test/cpp/naming/resolver_component_tests_runner_invoker.cc b/test/cpp/naming/resolver_component_tests_runner_invoker.cc
index b2a7890..45c1029 100644
--- a/test/cpp/naming/resolver_component_tests_runner_invoker.cc
+++ b/test/cpp/naming/resolver_component_tests_runner_invoker.cc
@@ -165,9 +165,9 @@
GPR_ASSERT(FLAGS_grpc_test_directory_relative_to_test_srcdir != "");
// Use bazel's TEST_SRCDIR environment variable to locate the "test data"
// binaries.
+ char* test_srcdir = gpr_getenv("TEST_SRCDIR");
std::string const bin_dir =
- gpr_getenv("TEST_SRCDIR") +
- FLAGS_grpc_test_directory_relative_to_test_srcdir +
+ test_srcdir + FLAGS_grpc_test_directory_relative_to_test_srcdir +
std::string("/test/cpp/naming");
// Invoke bazel's executeable links to the .sh and .py scripts (don't use
// the .sh and .py suffixes) to make
@@ -177,13 +177,14 @@
bin_dir + "/" + FLAGS_test_bin_name, bin_dir + "/utils/dns_server",
bin_dir + "/resolver_test_record_groups.yaml",
bin_dir + "/utils/dns_resolver", bin_dir + "/utils/tcp_connect");
+ gpr_free(test_srcdir);
} else {
// Get the current binary's directory relative to repo root to invoke the
// correct build config (asan/tsan/dbg, etc.).
std::string const bin_dir = my_bin.substr(0, my_bin.rfind('/'));
// Invoke the .sh and .py scripts directly where they are in source code.
grpc::testing::InvokeResolverComponentTestsRunner(
- "test/cpp/naming/resolver_component_tests_runner.sh",
+ "test/cpp/naming/resolver_component_tests_runner.py",
bin_dir + "/" + FLAGS_test_bin_name,
"test/cpp/naming/utils/dns_server.py",
"test/cpp/naming/resolver_test_record_groups.yaml",
diff --git a/test/cpp/naming/utils/dns_resolver.py b/test/cpp/naming/utils/dns_resolver.py
index 6b27244..74f4ca2 100755
--- a/test/cpp/naming/utils/dns_resolver.py
+++ b/test/cpp/naming/utils/dns_resolver.py
@@ -16,9 +16,12 @@
"""Makes DNS queries for A records to specified servers"""
import argparse
-import signal
+import threading
+import time
import twisted.internet.task as task
import twisted.names.client as client
+import twisted.internet.reactor as reactor
+
def main():
argp = argparse.ArgumentParser(description='Make DNS queries for A records')
@@ -31,7 +34,6 @@
argp.add_argument('-t', '--timeout', default=1, type=int,
help=('Force process exit after this number of seconds.'))
args = argp.parse_args()
- signal.alarm(args.timeout)
def OnResolverResultAvailable(result):
answers, authority, additional = result
for a in answers:
diff --git a/test/cpp/naming/utils/dns_server.py b/test/cpp/naming/utils/dns_server.py
index 9f42f65..1e8e2e3 100755
--- a/test/cpp/naming/utils/dns_server.py
+++ b/test/cpp/naming/utils/dns_server.py
@@ -20,6 +20,8 @@
import yaml
import signal
import os
+import threading
+import time
import twisted
import twisted.internet
@@ -33,6 +35,7 @@
import twisted.names.server
from twisted.names import client, server, common, authority, dns
import argparse
+import platform
_SERVER_HEALTH_CHECK_RECORD_NAME = 'health-check-local-dns-server-is-alive.resolver-tests.grpctestingexp' # missing end '.' for twisted syntax
_SERVER_HEALTH_CHECK_RECORD_DATA = '123.123.123.123'
@@ -115,6 +118,18 @@
sys.stdout.flush()
sys.exit(0)
+def flush_stdout_loop():
+ num_timeouts_so_far = 0
+ sleep_time = 1
+ # Prevent zombies. Tests that use this server are short-lived.
+ max_timeouts = 60 * 2
+ while num_timeouts_so_far < max_timeouts:
+ sys.stdout.flush()
+ time.sleep(sleep_time)
+ num_timeouts_so_far += 1
+ print('Process timeout reached, or cancelled. Exitting 0.')
+ os.kill(os.getpid(), signal.SIGTERM)
+
def main():
argp = argparse.ArgumentParser(description='Local DNS Server for resolver tests')
argp.add_argument('-p', '--port', default=None, type=int,
@@ -123,11 +138,11 @@
help=('Directory of resolver_test_record_groups.yaml file. '
'Defauls to path needed when the test is invoked as part of run_tests.py.'))
args = argp.parse_args()
- signal.signal(signal.SIGALRM, _quit_on_signal)
signal.signal(signal.SIGTERM, _quit_on_signal)
signal.signal(signal.SIGINT, _quit_on_signal)
- # Prevent zombies. Tests that use this server are short-lived.
- signal.alarm(2 * 60)
+ output_flush_thread = threading.Thread(target=flush_stdout_loop)
+ output_flush_thread.setDaemon(True)
+ output_flush_thread.start()
start_local_dns_server(args)
if __name__ == '__main__':
diff --git a/test/cpp/naming/utils/tcp_connect.py b/test/cpp/naming/utils/tcp_connect.py
index bf7455e..5773c7c 100755
--- a/test/cpp/naming/utils/tcp_connect.py
+++ b/test/cpp/naming/utils/tcp_connect.py
@@ -16,8 +16,11 @@
"""Opens a TCP connection to a specified server and then exits."""
import argparse
-import signal
import socket
+import threading
+import time
+import sys
+
def main():
argp = argparse.ArgumentParser(description='Open a TCP handshake to a server')
@@ -28,7 +31,6 @@
argp.add_argument('-t', '--timeout', default=1, type=int,
help='Force process exit after this number of seconds.')
args = argp.parse_args()
- signal.alarm(args.timeout)
socket.create_connection([args.server_host, args.server_port])
if __name__ == '__main__':
diff --git a/test/cpp/qps/BUILD b/test/cpp/qps/BUILD
index f1abb19..a348b88 100644
--- a/test/cpp/qps/BUILD
+++ b/test/cpp/qps/BUILD
@@ -47,9 +47,10 @@
"//:grpc",
"//:grpc++",
"//:grpc++_core_stats",
+ "//src/proto/grpc/testing:benchmark_service_proto",
"//src/proto/grpc/testing:control_proto",
"//src/proto/grpc/testing:payloads_proto",
- "//src/proto/grpc/testing:services_proto",
+ "//src/proto/grpc/testing:worker_service_proto",
"//test/core/end2end:ssl_test_data",
"//test/core/util:gpr_test_util",
"//test/core/util:grpc_test_util",
@@ -74,7 +75,8 @@
"//:grpc++",
"//src/proto/grpc/testing:control_proto",
"//src/proto/grpc/testing:messages_proto",
- "//src/proto/grpc/testing:services_proto",
+ "//src/proto/grpc/testing:report_qps_scenario_service_proto",
+ "//src/proto/grpc/testing:worker_service_proto",
"//test/core/util:gpr_test_util",
"//test/core/util:grpc_test_util",
"//test/cpp/util:test_util",
diff --git a/test/cpp/qps/client.h b/test/cpp/qps/client.h
index 77743a1..31ae6ca 100644
--- a/test/cpp/qps/client.h
+++ b/test/cpp/qps/client.h
@@ -31,8 +31,8 @@
#include <grpcpp/support/channel_arguments.h>
#include <grpcpp/support/slice.h>
+#include "src/proto/grpc/testing/benchmark_service.grpc.pb.h"
#include "src/proto/grpc/testing/payloads.pb.h"
-#include "src/proto/grpc/testing/services.grpc.pb.h"
#include "src/cpp/util/core_stats.h"
#include "test/cpp/qps/histogram.h"
diff --git a/test/cpp/qps/client_async.cc b/test/cpp/qps/client_async.cc
index f9bef91..c79a10d 100644
--- a/test/cpp/qps/client_async.cc
+++ b/test/cpp/qps/client_async.cc
@@ -35,7 +35,7 @@
#include <grpcpp/generic/generic_stub.h>
#include "src/core/lib/surface/completion_queue.h"
-#include "src/proto/grpc/testing/services.grpc.pb.h"
+#include "src/proto/grpc/testing/benchmark_service.grpc.pb.h"
#include "test/cpp/qps/client.h"
#include "test/cpp/qps/usage_timer.h"
#include "test/cpp/util/create_test_channel.h"
diff --git a/test/cpp/qps/client_sync.cc b/test/cpp/qps/client_sync.cc
index 5185eef..e65e3b4 100644
--- a/test/cpp/qps/client_sync.cc
+++ b/test/cpp/qps/client_sync.cc
@@ -35,7 +35,7 @@
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/profiling/timers.h"
-#include "src/proto/grpc/testing/services.grpc.pb.h"
+#include "src/proto/grpc/testing/benchmark_service.grpc.pb.h"
#include "test/cpp/qps/client.h"
#include "test/cpp/qps/interarrival.h"
#include "test/cpp/qps/usage_timer.h"
diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc
index 361ee43..34f1291 100644
--- a/test/cpp/qps/driver.cc
+++ b/test/cpp/qps/driver.cc
@@ -33,6 +33,7 @@
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/profiling/timers.h"
+#include "src/proto/grpc/testing/worker_service.grpc.pb.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
#include "test/cpp/qps/client.h"
diff --git a/test/cpp/qps/gen_build_yaml.py b/test/cpp/qps/gen_build_yaml.py
index 1ef8f65..776283c 100755
--- a/test/cpp/qps/gen_build_yaml.py
+++ b/test/cpp/qps/gen_build_yaml.py
@@ -63,6 +63,11 @@
return (scenario_json['num_clients'] * client +
scenario_json['num_servers'] * server)
+def maybe_exclude_gcov(scenario_json):
+ if scenario_json['client_config']['client_channels'] > 100:
+ return ['gcov']
+ return []
+
print yaml.dump({
'tests': [
{
@@ -76,7 +81,7 @@
'boringssl': True,
'defaults': 'boringssl',
'cpu_cost': guess_cpu(scenario_json, False),
- 'exclude_configs': ['tsan', 'asan'],
+ 'exclude_configs': ['tsan', 'asan'] + maybe_exclude_gcov(scenario_json),
'timeout_seconds': 2*60,
'excluded_poll_engines': scenario_json.get('EXCLUDED_POLL_ENGINES', []),
'auto_timeout_scaling': False
diff --git a/test/cpp/qps/qps_worker.cc b/test/cpp/qps/qps_worker.cc
index aaffb1d..d3f0380 100644
--- a/test/cpp/qps/qps_worker.cc
+++ b/test/cpp/qps/qps_worker.cc
@@ -35,7 +35,7 @@
#include <grpcpp/server_builder.h>
#include "src/core/lib/gpr/host_port.h"
-#include "src/proto/grpc/testing/services.pb.h"
+#include "src/proto/grpc/testing/worker_service.grpc.pb.h"
#include "test/core/util/grpc_profiler.h"
#include "test/core/util/histogram.h"
#include "test/cpp/qps/client.h"
diff --git a/test/cpp/qps/report.cc b/test/cpp/qps/report.cc
index 0a2565d..607f4e5 100644
--- a/test/cpp/qps/report.cc
+++ b/test/cpp/qps/report.cc
@@ -27,7 +27,7 @@
#include <grpcpp/client_context.h>
#include "src/cpp/util/core_stats.h"
-#include "src/proto/grpc/testing/services.grpc.pb.h"
+#include "src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.h"
namespace grpc {
namespace testing {
diff --git a/test/cpp/qps/report.h b/test/cpp/qps/report.h
index c5dd138..8e62f4f 100644
--- a/test/cpp/qps/report.h
+++ b/test/cpp/qps/report.h
@@ -28,7 +28,7 @@
#include "test/cpp/qps/driver.h"
#include <grpcpp/channel.h>
-#include "src/proto/grpc/testing/services.grpc.pb.h"
+#include "src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.h"
namespace grpc {
namespace testing {
diff --git a/test/cpp/qps/server_async.cc b/test/cpp/qps/server_async.cc
index 9cb05cd..1dfef6c 100644
--- a/test/cpp/qps/server_async.cc
+++ b/test/cpp/qps/server_async.cc
@@ -36,7 +36,7 @@
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/surface/completion_queue.h"
-#include "src/proto/grpc/testing/services.grpc.pb.h"
+#include "src/proto/grpc/testing/benchmark_service.grpc.pb.h"
#include "test/core/util/test_config.h"
#include "test/cpp/qps/server.h"
diff --git a/test/cpp/qps/server_sync.cc b/test/cpp/qps/server_sync.cc
index 9dfd362..82a9186 100644
--- a/test/cpp/qps/server_sync.cc
+++ b/test/cpp/qps/server_sync.cc
@@ -26,7 +26,7 @@
#include <grpcpp/server_context.h>
#include "src/core/lib/gpr/host_port.h"
-#include "src/proto/grpc/testing/services.grpc.pb.h"
+#include "src/proto/grpc/testing/benchmark_service.grpc.pb.h"
#include "test/cpp/qps/server.h"
#include "test/cpp/qps/usage_timer.h"
diff --git a/test/cpp/server/BUILD b/test/cpp/server/BUILD
index 7538845..3f89d6e 100644
--- a/test/cpp/server/BUILD
+++ b/test/cpp/server/BUILD
@@ -32,6 +32,19 @@
)
grpc_cc_test(
+ name = "server_builder_with_socket_mutator_test",
+ srcs = ["server_builder_with_socket_mutator_test.cc"],
+ deps = [
+ "//:grpc++_unsecure",
+ "//src/proto/grpc/testing:echo_proto",
+ "//test/core/util:grpc_test_util_unsecure",
+ ],
+ external_deps = [
+ "gtest",
+ ],
+)
+
+grpc_cc_test(
name = "server_request_call_test",
srcs = ["server_request_call_test.cc"],
deps = [
diff --git a/test/cpp/server/load_reporter/BUILD b/test/cpp/server/load_reporter/BUILD
new file mode 100644
index 0000000..5cb3a00
--- /dev/null
+++ b/test/cpp/server/load_reporter/BUILD
@@ -0,0 +1,31 @@
+# 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.
+
+licenses(["notice"]) # Apache v2
+
+load("//bazel:grpc_build_system.bzl", "grpc_cc_test", "grpc_cc_library", "grpc_cc_binary", "grpc_package")
+
+grpc_package(name = "test/cpp/server/load_reporter")
+
+grpc_cc_test(
+ name = "lb_load_data_store_test",
+ srcs = ["load_data_store_test.cc"],
+ external_deps = [
+ "gtest",
+ ],
+ deps = [
+ "//:lb_load_data_store",
+ "//test/core/util:grpc_test_util",
+ ],
+)
diff --git a/test/cpp/server/load_reporter/load_data_store_test.cc b/test/cpp/server/load_reporter/load_data_store_test.cc
new file mode 100644
index 0000000..8280dee
--- /dev/null
+++ b/test/cpp/server/load_reporter/load_data_store_test.cc
@@ -0,0 +1,481 @@
+/*
+ *
+ * Copyright 2018 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.
+ *
+ */
+
+#include <grpc/impl/codegen/port_platform.h>
+
+#include <set>
+#include <vector>
+
+#include <grpc/grpc.h>
+#include <gtest/gtest.h>
+
+#include "src/cpp/server/load_reporter/load_data_store.h"
+#include "test/core/util/port.h"
+#include "test/core/util/test_config.h"
+
+namespace grpc {
+namespace testing {
+namespace {
+
+using ::grpc::load_reporter::CallMetricValue;
+using ::grpc::load_reporter::LoadDataStore;
+using ::grpc::load_reporter::LoadRecordKey;
+using ::grpc::load_reporter::LoadRecordValue;
+using ::grpc::load_reporter::PerBalancerStore;
+using ::grpc::load_reporter::kInvalidLbId;
+
+class LoadDataStoreTest : public ::testing::Test {
+ public:
+ LoadDataStoreTest()
+ : kKey1(kLbId1, kLbTag1, kUser1, kClientIp1),
+ kKey2(kLbId2, kLbTag2, kUser2, kClientIp2) {}
+
+ // Check whether per_balancer_stores contains a store which was originally
+ // created for <hostname, lb_id, and load_key>.
+ bool PerBalancerStoresContains(
+ const LoadDataStore& load_data_store,
+ const std::set<PerBalancerStore*>* per_balancer_stores,
+ const grpc::string hostname, const grpc::string lb_id,
+ const grpc::string load_key) {
+ auto original_per_balancer_store =
+ load_data_store.FindPerBalancerStore(hostname, lb_id);
+ EXPECT_NE(original_per_balancer_store, nullptr);
+ EXPECT_EQ(original_per_balancer_store->lb_id(), lb_id);
+ EXPECT_EQ(original_per_balancer_store->load_key(), load_key);
+ for (auto per_balancer_store : *per_balancer_stores) {
+ if (per_balancer_store == original_per_balancer_store) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ grpc::string FormatLbId(size_t index) {
+ return "kLbId" + std::to_string(index);
+ }
+
+ const grpc::string kHostname1 = "kHostname1";
+ const grpc::string kHostname2 = "kHostname2";
+ const grpc::string kLbId1 = "kLbId1";
+ const grpc::string kLbId2 = "kLbId2";
+ const grpc::string kLbId3 = "kLbId3";
+ const grpc::string kLbId4 = "kLbId4";
+ const grpc::string kLoadKey1 = "kLoadKey1";
+ const grpc::string kLoadKey2 = "kLoadKey2";
+ const grpc::string kLbTag1 = "kLbTag1";
+ const grpc::string kLbTag2 = "kLbTag2";
+ const grpc::string kUser1 = "kUser1";
+ const grpc::string kUser2 = "kUser2";
+ const grpc::string kClientIp1 = "00";
+ const grpc::string kClientIp2 = "02";
+ const grpc::string kMetric1 = "kMetric1";
+ const grpc::string kMetric2 = "kMetric2";
+ const LoadRecordKey kKey1;
+ const LoadRecordKey kKey2;
+};
+
+using PerBalancerStoreTest = LoadDataStoreTest;
+
+TEST_F(LoadDataStoreTest, AssignToSelf) {
+ LoadDataStore load_data_store;
+ load_data_store.ReportStreamCreated(kHostname1, kLbId1, kLoadKey1);
+ auto assigned_stores = load_data_store.GetAssignedStores(kHostname1, kLbId1);
+ EXPECT_TRUE(PerBalancerStoresContains(load_data_store, assigned_stores,
+ kHostname1, kLbId1, kLoadKey1));
+}
+
+TEST_F(LoadDataStoreTest, ReassignOrphanStores) {
+ LoadDataStore load_data_store;
+ load_data_store.ReportStreamCreated(kHostname1, kLbId1, kLoadKey1);
+ load_data_store.ReportStreamCreated(kHostname1, kLbId2, kLoadKey1);
+ load_data_store.ReportStreamCreated(kHostname1, kLbId3, kLoadKey2);
+ load_data_store.ReportStreamCreated(kHostname2, kLbId4, kLoadKey1);
+ // 1. Close the second stream.
+ load_data_store.ReportStreamClosed(kHostname1, kLbId2);
+ auto assigned_to_lb_id_1 =
+ load_data_store.GetAssignedStores(kHostname1, kLbId1);
+ // The orphaned store is re-assigned to kLbId1 with the same load key.
+ EXPECT_TRUE(PerBalancerStoresContains(load_data_store, assigned_to_lb_id_1,
+ kHostname1, kLbId1, kLoadKey1));
+ EXPECT_TRUE(PerBalancerStoresContains(load_data_store, assigned_to_lb_id_1,
+ kHostname1, kLbId2, kLoadKey1));
+ // 2. Close the first stream.
+ load_data_store.ReportStreamClosed(kHostname1, kLbId1);
+ auto assigned_to_lb_id_3 =
+ load_data_store.GetAssignedStores(kHostname1, kLbId3);
+ // The orphaned stores are re-assigned to kLbId3 with the same host,
+ // because there isn't any LB with the same load key.
+ EXPECT_TRUE(PerBalancerStoresContains(load_data_store, assigned_to_lb_id_3,
+ kHostname1, kLbId1, kLoadKey1));
+ EXPECT_TRUE(PerBalancerStoresContains(load_data_store, assigned_to_lb_id_3,
+ kHostname1, kLbId2, kLoadKey1));
+ EXPECT_TRUE(PerBalancerStoresContains(load_data_store, assigned_to_lb_id_3,
+ kHostname1, kLbId3, kLoadKey2));
+ // 3. Close the third stream.
+ load_data_store.ReportStreamClosed(kHostname1, kLbId3);
+ auto assigned_to_lb_id_4 =
+ load_data_store.GetAssignedStores(kHostname2, kLbId4);
+ // There is no active LB for the first host now. kLbId4 is active but
+ // it's for the second host, so it wll NOT adopt the orphaned stores.
+ EXPECT_FALSE(PerBalancerStoresContains(load_data_store, assigned_to_lb_id_4,
+ kHostname1, kLbId1, kLoadKey1));
+ EXPECT_FALSE(PerBalancerStoresContains(load_data_store, assigned_to_lb_id_4,
+ kHostname1, kLbId2, kLoadKey1));
+ EXPECT_FALSE(PerBalancerStoresContains(load_data_store, assigned_to_lb_id_4,
+ kHostname1, kLbId3, kLoadKey2));
+ EXPECT_TRUE(PerBalancerStoresContains(load_data_store, assigned_to_lb_id_4,
+ kHostname2, kLbId4, kLoadKey1));
+}
+
+TEST_F(LoadDataStoreTest, OrphanAssignmentIsSticky) {
+ LoadDataStore load_data_store;
+ std::set<grpc::string> active_lb_ids;
+ size_t num_lb_ids = 1000;
+ for (size_t i = 0; i < num_lb_ids; ++i) {
+ load_data_store.ReportStreamCreated(kHostname1, FormatLbId(i), kLoadKey1);
+ active_lb_ids.insert(FormatLbId(i));
+ }
+ grpc::string orphaned_lb_id = FormatLbId(std::rand() % num_lb_ids);
+ load_data_store.ReportStreamClosed(kHostname1, orphaned_lb_id);
+ active_lb_ids.erase(orphaned_lb_id);
+ // Find which LB is assigned the orphaned store.
+ grpc::string assigned_lb_id = "";
+ for (auto lb_id : active_lb_ids) {
+ if (PerBalancerStoresContains(
+ load_data_store,
+ load_data_store.GetAssignedStores(kHostname1, lb_id), kHostname1,
+ orphaned_lb_id, kLoadKey1)) {
+ assigned_lb_id = lb_id;
+ break;
+ }
+ }
+ EXPECT_STRNE(assigned_lb_id.c_str(), "");
+ // Close 10 more stream, skipping the assigned_lb_id. The assignment of
+ // orphaned_lb_id shouldn't change.
+ for (size_t _ = 0; _ < 10; ++_) {
+ grpc::string lb_id_to_close = "";
+ for (auto lb_id : active_lb_ids) {
+ if (lb_id != assigned_lb_id) {
+ lb_id_to_close = lb_id;
+ break;
+ }
+ }
+ EXPECT_STRNE(lb_id_to_close.c_str(), "");
+ load_data_store.ReportStreamClosed(kHostname1, lb_id_to_close);
+ active_lb_ids.erase(lb_id_to_close);
+ EXPECT_TRUE(PerBalancerStoresContains(
+ load_data_store,
+ load_data_store.GetAssignedStores(kHostname1, assigned_lb_id),
+ kHostname1, orphaned_lb_id, kLoadKey1));
+ }
+ // Close the assigned_lb_id, orphaned_lb_id will be re-assigned again.
+ load_data_store.ReportStreamClosed(kHostname1, assigned_lb_id);
+ active_lb_ids.erase(assigned_lb_id);
+ size_t orphaned_lb_id_occurences = 0;
+ for (auto lb_id : active_lb_ids) {
+ if (PerBalancerStoresContains(
+ load_data_store,
+ load_data_store.GetAssignedStores(kHostname1, lb_id), kHostname1,
+ orphaned_lb_id, kLoadKey1)) {
+ orphaned_lb_id_occurences++;
+ }
+ }
+ EXPECT_EQ(orphaned_lb_id_occurences, 1U);
+}
+
+TEST_F(LoadDataStoreTest, HostTemporarilyLoseAllStreams) {
+ LoadDataStore load_data_store;
+ load_data_store.ReportStreamCreated(kHostname1, kLbId1, kLoadKey1);
+ load_data_store.ReportStreamCreated(kHostname2, kLbId2, kLoadKey1);
+ auto store_lb_id_1 = load_data_store.FindPerBalancerStore(kHostname1, kLbId1);
+ auto store_invalid_lb_id_1 =
+ load_data_store.FindPerBalancerStore(kHostname1, kInvalidLbId);
+ EXPECT_FALSE(store_lb_id_1->IsSuspended());
+ EXPECT_FALSE(store_invalid_lb_id_1->IsSuspended());
+ // Disconnect all the streams of the first host.
+ load_data_store.ReportStreamClosed(kHostname1, kLbId1);
+ // All the streams of that host are suspended.
+ EXPECT_TRUE(store_lb_id_1->IsSuspended());
+ EXPECT_TRUE(store_invalid_lb_id_1->IsSuspended());
+ // Detailed load data won't be kept when the PerBalancerStore is suspended.
+ store_lb_id_1->MergeRow(kKey1, LoadRecordValue());
+ store_invalid_lb_id_1->MergeRow(kKey1, LoadRecordValue());
+ EXPECT_EQ(store_lb_id_1->load_record_map().size(), 0U);
+ EXPECT_EQ(store_invalid_lb_id_1->load_record_map().size(), 0U);
+ // The stores for different hosts won't mix, even if the load key is the same.
+ auto assigned_to_lb_id_2 =
+ load_data_store.GetAssignedStores(kHostname2, kLbId2);
+ EXPECT_EQ(assigned_to_lb_id_2->size(), 2U);
+ EXPECT_TRUE(PerBalancerStoresContains(load_data_store, assigned_to_lb_id_2,
+ kHostname2, kLbId2, kLoadKey1));
+ EXPECT_TRUE(PerBalancerStoresContains(load_data_store, assigned_to_lb_id_2,
+ kHostname2, kInvalidLbId, ""));
+ // A new stream is created for the first host.
+ load_data_store.ReportStreamCreated(kHostname1, kLbId3, kLoadKey2);
+ // The stores for the first host are resumed.
+ EXPECT_FALSE(store_lb_id_1->IsSuspended());
+ EXPECT_FALSE(store_invalid_lb_id_1->IsSuspended());
+ store_lb_id_1->MergeRow(kKey1, LoadRecordValue());
+ store_invalid_lb_id_1->MergeRow(kKey1, LoadRecordValue());
+ EXPECT_EQ(store_lb_id_1->load_record_map().size(), 1U);
+ EXPECT_EQ(store_invalid_lb_id_1->load_record_map().size(), 1U);
+ // The resumed stores are assigned to the new LB.
+ auto assigned_to_lb_id_3 =
+ load_data_store.GetAssignedStores(kHostname1, kLbId3);
+ EXPECT_EQ(assigned_to_lb_id_3->size(), 3U);
+ EXPECT_TRUE(PerBalancerStoresContains(load_data_store, assigned_to_lb_id_3,
+ kHostname1, kLbId1, kLoadKey1));
+ EXPECT_TRUE(PerBalancerStoresContains(load_data_store, assigned_to_lb_id_3,
+ kHostname1, kInvalidLbId, ""));
+ EXPECT_TRUE(PerBalancerStoresContains(load_data_store, assigned_to_lb_id_3,
+ kHostname1, kLbId3, kLoadKey2));
+}
+
+TEST_F(LoadDataStoreTest, OneStorePerLbId) {
+ LoadDataStore load_data_store;
+ EXPECT_EQ(load_data_store.FindPerBalancerStore(kHostname1, kLbId1), nullptr);
+ EXPECT_EQ(load_data_store.FindPerBalancerStore(kHostname1, kInvalidLbId),
+ nullptr);
+ EXPECT_EQ(load_data_store.FindPerBalancerStore(kHostname2, kLbId2), nullptr);
+ EXPECT_EQ(load_data_store.FindPerBalancerStore(kHostname2, kLbId3), nullptr);
+ // Create The first stream.
+ load_data_store.ReportStreamCreated(kHostname1, kLbId1, kLoadKey1);
+ auto store_lb_id_1 = load_data_store.FindPerBalancerStore(kHostname1, kLbId1);
+ auto store_invalid_lb_id_1 =
+ load_data_store.FindPerBalancerStore(kHostname1, kInvalidLbId);
+ // Two stores will be created: one is for the stream; the other one is for
+ // kInvalidLbId.
+ EXPECT_NE(store_lb_id_1, nullptr);
+ EXPECT_NE(store_invalid_lb_id_1, nullptr);
+ EXPECT_NE(store_lb_id_1, store_invalid_lb_id_1);
+ EXPECT_EQ(load_data_store.FindPerBalancerStore(kHostname2, kLbId2), nullptr);
+ EXPECT_EQ(load_data_store.FindPerBalancerStore(kHostname2, kLbId3), nullptr);
+ // Create the second stream.
+ load_data_store.ReportStreamCreated(kHostname2, kLbId3, kLoadKey1);
+ auto store_lb_id_3 = load_data_store.FindPerBalancerStore(kHostname2, kLbId3);
+ auto store_invalid_lb_id_2 =
+ load_data_store.FindPerBalancerStore(kHostname2, kInvalidLbId);
+ EXPECT_NE(store_lb_id_3, nullptr);
+ EXPECT_NE(store_invalid_lb_id_2, nullptr);
+ EXPECT_NE(store_lb_id_3, store_invalid_lb_id_2);
+ // The PerBalancerStores created for different hosts are independent.
+ EXPECT_NE(store_lb_id_3, store_invalid_lb_id_1);
+ EXPECT_NE(store_invalid_lb_id_2, store_invalid_lb_id_1);
+ EXPECT_EQ(load_data_store.FindPerBalancerStore(kHostname2, kLbId2), nullptr);
+}
+
+TEST_F(LoadDataStoreTest, ExactlyOnceAssignment) {
+ LoadDataStore load_data_store;
+ size_t num_create = 100;
+ size_t num_close = 50;
+ for (size_t i = 0; i < num_create; ++i) {
+ load_data_store.ReportStreamCreated(kHostname1, FormatLbId(i), kLoadKey1);
+ }
+ for (size_t i = 0; i < num_close; ++i) {
+ load_data_store.ReportStreamClosed(kHostname1, FormatLbId(i));
+ }
+ std::set<grpc::string> reported_lb_ids;
+ for (size_t i = num_close; i < num_create; ++i) {
+ for (auto assigned_store :
+ *load_data_store.GetAssignedStores(kHostname1, FormatLbId(i))) {
+ EXPECT_TRUE(reported_lb_ids.insert(assigned_store->lb_id()).second);
+ }
+ }
+ // Add one for kInvalidLbId.
+ EXPECT_EQ(reported_lb_ids.size(), (num_create + 1));
+ EXPECT_NE(reported_lb_ids.find(kInvalidLbId), reported_lb_ids.end());
+}
+
+TEST_F(LoadDataStoreTest, UnknownBalancerIdTracking) {
+ LoadDataStore load_data_store;
+ load_data_store.ReportStreamCreated(kHostname1, kLbId1, kLoadKey1);
+ // Merge data for a known LB ID.
+ LoadRecordValue v1(192);
+ load_data_store.MergeRow(kHostname1, kKey1, v1);
+ // Merge data for unknown LB ID.
+ LoadRecordValue v2(23);
+ EXPECT_FALSE(load_data_store.IsTrackedUnknownBalancerId(kLbId2));
+ load_data_store.MergeRow(
+ kHostname1, LoadRecordKey(kLbId2, kLbTag1, kUser1, kClientIp1), v2);
+ EXPECT_TRUE(load_data_store.IsTrackedUnknownBalancerId(kLbId2));
+ LoadRecordValue v3(952);
+ load_data_store.MergeRow(
+ kHostname2, LoadRecordKey(kLbId3, kLbTag1, kUser1, kClientIp1), v3);
+ EXPECT_TRUE(load_data_store.IsTrackedUnknownBalancerId(kLbId3));
+ // The data kept for a known LB ID is correct.
+ auto store_lb_id_1 = load_data_store.FindPerBalancerStore(kHostname1, kLbId1);
+ EXPECT_EQ(store_lb_id_1->load_record_map().size(), 1U);
+ EXPECT_EQ(store_lb_id_1->load_record_map().find(kKey1)->second.start_count(),
+ v1.start_count());
+ EXPECT_EQ(store_lb_id_1->GetNumCallsInProgressForReport(), v1.start_count());
+ // No PerBalancerStore created for Unknown LB ID.
+ EXPECT_EQ(load_data_store.FindPerBalancerStore(kHostname1, kLbId2), nullptr);
+ EXPECT_EQ(load_data_store.FindPerBalancerStore(kHostname2, kLbId3), nullptr);
+ // End all the started RPCs for kLbId1.
+ LoadRecordValue v4(0, v1.start_count());
+ load_data_store.MergeRow(kHostname1, kKey1, v4);
+ EXPECT_EQ(store_lb_id_1->load_record_map().size(), 1U);
+ EXPECT_EQ(store_lb_id_1->load_record_map().find(kKey1)->second.start_count(),
+ v1.start_count());
+ EXPECT_EQ(store_lb_id_1->load_record_map().find(kKey1)->second.ok_count(),
+ v4.ok_count());
+ EXPECT_EQ(store_lb_id_1->GetNumCallsInProgressForReport(), 0U);
+ EXPECT_FALSE(load_data_store.IsTrackedUnknownBalancerId(kLbId1));
+ // End all the started RPCs for kLbId2.
+ LoadRecordValue v5(0, v2.start_count());
+ load_data_store.MergeRow(
+ kHostname1, LoadRecordKey(kLbId2, kLbTag1, kUser1, kClientIp1), v5);
+ EXPECT_FALSE(load_data_store.IsTrackedUnknownBalancerId(kLbId2));
+ // End some of the started RPCs for kLbId3.
+ LoadRecordValue v6(0, v3.start_count() / 2);
+ load_data_store.MergeRow(
+ kHostname2, LoadRecordKey(kLbId3, kLbTag1, kUser1, kClientIp1), v6);
+ EXPECT_TRUE(load_data_store.IsTrackedUnknownBalancerId(kLbId3));
+}
+
+TEST_F(PerBalancerStoreTest, Suspend) {
+ PerBalancerStore per_balancer_store(kLbId1, kLoadKey1);
+ EXPECT_FALSE(per_balancer_store.IsSuspended());
+ // Suspend the store.
+ per_balancer_store.Suspend();
+ EXPECT_TRUE(per_balancer_store.IsSuspended());
+ EXPECT_EQ(0U, per_balancer_store.load_record_map().size());
+ // Data merged when the store is suspended won't be kept.
+ LoadRecordValue v1(139, 19);
+ per_balancer_store.MergeRow(kKey1, v1);
+ EXPECT_EQ(0U, per_balancer_store.load_record_map().size());
+ // Resume the store.
+ per_balancer_store.Resume();
+ EXPECT_FALSE(per_balancer_store.IsSuspended());
+ EXPECT_EQ(0U, per_balancer_store.load_record_map().size());
+ // Data merged after the store is resumed will be kept.
+ LoadRecordValue v2(23, 0, 51);
+ per_balancer_store.MergeRow(kKey1, v2);
+ EXPECT_EQ(1U, per_balancer_store.load_record_map().size());
+ // Suspend the store.
+ per_balancer_store.Suspend();
+ EXPECT_TRUE(per_balancer_store.IsSuspended());
+ EXPECT_EQ(0U, per_balancer_store.load_record_map().size());
+ // Data merged when the store is suspended won't be kept.
+ LoadRecordValue v3(62, 11);
+ per_balancer_store.MergeRow(kKey1, v3);
+ EXPECT_EQ(0U, per_balancer_store.load_record_map().size());
+ // Resume the store.
+ per_balancer_store.Resume();
+ EXPECT_FALSE(per_balancer_store.IsSuspended());
+ EXPECT_EQ(0U, per_balancer_store.load_record_map().size());
+ // Data merged after the store is resumed will be kept.
+ LoadRecordValue v4(225, 98);
+ per_balancer_store.MergeRow(kKey1, v4);
+ EXPECT_EQ(1U, per_balancer_store.load_record_map().size());
+ // In-progress count is always kept.
+ EXPECT_EQ(per_balancer_store.GetNumCallsInProgressForReport(),
+ v1.start_count() - v1.ok_count() + v2.start_count() -
+ v2.error_count() + v3.start_count() - v3.ok_count() +
+ v4.start_count() - v4.ok_count());
+}
+
+TEST_F(PerBalancerStoreTest, DataAggregation) {
+ PerBalancerStore per_balancer_store(kLbId1, kLoadKey1);
+ // Construct some Values.
+ LoadRecordValue v1(992, 34, 13, 234.0, 164.0, 173467.38);
+ v1.InsertCallMetric(kMetric1, CallMetricValue(3, 2773.2));
+ LoadRecordValue v2(4842, 213, 9, 393.0, 974.0, 1345.2398);
+ v2.InsertCallMetric(kMetric1, CallMetricValue(7, 25.234));
+ v2.InsertCallMetric(kMetric2, CallMetricValue(2, 387.08));
+ // v3 doesn't change the number of in-progress RPCs.
+ LoadRecordValue v3(293, 55, 293 - 55, 28764, 5284, 5772);
+ v3.InsertCallMetric(kMetric1, CallMetricValue(61, 3465.0));
+ v3.InsertCallMetric(kMetric2, CallMetricValue(13, 672.0));
+ // The initial state of the store.
+ uint64_t num_calls_in_progress = 0;
+ EXPECT_FALSE(per_balancer_store.IsNumCallsInProgressChangedSinceLastReport());
+ EXPECT_EQ(per_balancer_store.GetNumCallsInProgressForReport(),
+ num_calls_in_progress);
+ // Merge v1 and get report of the number of in-progress calls.
+ per_balancer_store.MergeRow(kKey1, v1);
+ EXPECT_TRUE(per_balancer_store.IsNumCallsInProgressChangedSinceLastReport());
+ EXPECT_EQ(per_balancer_store.GetNumCallsInProgressForReport(),
+ num_calls_in_progress +=
+ (v1.start_count() - v1.ok_count() - v1.error_count()));
+ EXPECT_FALSE(per_balancer_store.IsNumCallsInProgressChangedSinceLastReport());
+ // Merge v2 and get report of the number of in-progress calls.
+ per_balancer_store.MergeRow(kKey2, v2);
+ EXPECT_TRUE(per_balancer_store.IsNumCallsInProgressChangedSinceLastReport());
+ EXPECT_EQ(per_balancer_store.GetNumCallsInProgressForReport(),
+ num_calls_in_progress +=
+ (v2.start_count() - v2.ok_count() - v2.error_count()));
+ EXPECT_FALSE(per_balancer_store.IsNumCallsInProgressChangedSinceLastReport());
+ // Merge v3 and get report of the number of in-progress calls.
+ per_balancer_store.MergeRow(kKey1, v3);
+ EXPECT_FALSE(per_balancer_store.IsNumCallsInProgressChangedSinceLastReport());
+ EXPECT_EQ(per_balancer_store.GetNumCallsInProgressForReport(),
+ num_calls_in_progress);
+ // LoadRecordValue for kKey1 is aggregated correctly.
+ LoadRecordValue value_for_key1 =
+ per_balancer_store.load_record_map().find(kKey1)->second;
+ EXPECT_EQ(value_for_key1.start_count(), v1.start_count() + v3.start_count());
+ EXPECT_EQ(value_for_key1.ok_count(), v1.ok_count() + v3.ok_count());
+ EXPECT_EQ(value_for_key1.error_count(), v1.error_count() + v3.error_count());
+ EXPECT_EQ(value_for_key1.bytes_sent(), v1.bytes_sent() + v3.bytes_sent());
+ EXPECT_EQ(value_for_key1.bytes_recv(), v1.bytes_recv() + v3.bytes_recv());
+ EXPECT_EQ(value_for_key1.latency_ms(), v1.latency_ms() + v3.latency_ms());
+ EXPECT_EQ(value_for_key1.call_metrics().size(), 2U);
+ EXPECT_EQ(value_for_key1.call_metrics().find(kMetric1)->second.num_calls(),
+ v1.call_metrics().find(kMetric1)->second.num_calls() +
+ v3.call_metrics().find(kMetric1)->second.num_calls());
+ EXPECT_EQ(
+ value_for_key1.call_metrics().find(kMetric1)->second.total_metric_value(),
+ v1.call_metrics().find(kMetric1)->second.total_metric_value() +
+ v3.call_metrics().find(kMetric1)->second.total_metric_value());
+ EXPECT_EQ(value_for_key1.call_metrics().find(kMetric2)->second.num_calls(),
+ v3.call_metrics().find(kMetric2)->second.num_calls());
+ EXPECT_EQ(
+ value_for_key1.call_metrics().find(kMetric2)->second.total_metric_value(),
+ v3.call_metrics().find(kMetric2)->second.total_metric_value());
+ // LoadRecordValue for kKey2 is aggregated (trivially) correctly.
+ LoadRecordValue value_for_key2 =
+ per_balancer_store.load_record_map().find(kKey2)->second;
+ EXPECT_EQ(value_for_key2.start_count(), v2.start_count());
+ EXPECT_EQ(value_for_key2.ok_count(), v2.ok_count());
+ EXPECT_EQ(value_for_key2.error_count(), v2.error_count());
+ EXPECT_EQ(value_for_key2.bytes_sent(), v2.bytes_sent());
+ EXPECT_EQ(value_for_key2.bytes_recv(), v2.bytes_recv());
+ EXPECT_EQ(value_for_key2.latency_ms(), v2.latency_ms());
+ EXPECT_EQ(value_for_key2.call_metrics().size(), 2U);
+ EXPECT_EQ(value_for_key2.call_metrics().find(kMetric1)->second.num_calls(),
+ v2.call_metrics().find(kMetric1)->second.num_calls());
+ EXPECT_EQ(
+ value_for_key2.call_metrics().find(kMetric1)->second.total_metric_value(),
+ v2.call_metrics().find(kMetric1)->second.total_metric_value());
+ EXPECT_EQ(value_for_key2.call_metrics().find(kMetric2)->second.num_calls(),
+ v2.call_metrics().find(kMetric2)->second.num_calls());
+ EXPECT_EQ(
+ value_for_key2.call_metrics().find(kMetric2)->second.total_metric_value(),
+ v2.call_metrics().find(kMetric2)->second.total_metric_value());
+}
+
+} // namespace
+} // namespace testing
+} // namespace grpc
+
+int main(int argc, char** argv) {
+ grpc_test_init(argc, argv);
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/test/cpp/server/server_builder_test.cc b/test/cpp/server/server_builder_test.cc
index 2752b58..5c22dda 100644
--- a/test/cpp/server/server_builder_test.cc
+++ b/test/cpp/server/server_builder_test.cc
@@ -39,7 +39,10 @@
return s.str();
}
-grpc::string g_port = MakePort();
+const grpc::string& GetPort() {
+ static grpc::string g_port = MakePort();
+ return g_port;
+}
TEST(ServerBuilderTest, NoOp) { ServerBuilder b; }
@@ -50,7 +53,7 @@
TEST(ServerBuilderTest, CreateServerOnePort) {
ServerBuilder()
.RegisterService(&g_service)
- .AddListeningPort(g_port, InsecureServerCredentials())
+ .AddListeningPort(GetPort(), InsecureServerCredentials())
.BuildAndStart()
->Shutdown();
}
@@ -58,8 +61,8 @@
TEST(ServerBuilderTest, CreateServerRepeatedPort) {
ServerBuilder()
.RegisterService(&g_service)
- .AddListeningPort(g_port, InsecureServerCredentials())
- .AddListeningPort(g_port, InsecureServerCredentials())
+ .AddListeningPort(GetPort(), InsecureServerCredentials())
+ .AddListeningPort(GetPort(), InsecureServerCredentials())
.BuildAndStart()
->Shutdown();
}
@@ -67,8 +70,8 @@
TEST(ServerBuilderTest, CreateServerRepeatedPortWithDisallowedReusePort) {
EXPECT_EQ(ServerBuilder()
.RegisterService(&g_service)
- .AddListeningPort(g_port, InsecureServerCredentials())
- .AddListeningPort(g_port, InsecureServerCredentials())
+ .AddListeningPort(GetPort(), InsecureServerCredentials())
+ .AddListeningPort(GetPort(), InsecureServerCredentials())
.AddChannelArgument(GRPC_ARG_ALLOW_REUSEPORT, 0)
.BuildAndStart(),
nullptr);
diff --git a/test/cpp/server/server_builder_with_socket_mutator_test.cc b/test/cpp/server/server_builder_with_socket_mutator_test.cc
new file mode 100644
index 0000000..5c7dd69
--- /dev/null
+++ b/test/cpp/server/server_builder_with_socket_mutator_test.cc
@@ -0,0 +1,116 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#include <grpcpp/impl/codegen/config.h>
+#include <gtest/gtest.h>
+
+#include <grpcpp/server.h>
+#include <grpcpp/server_builder.h>
+
+#include <grpc/grpc.h>
+#include <memory>
+
+#include "src/core/lib/iomgr/socket_mutator.h"
+#include "src/proto/grpc/testing/echo.grpc.pb.h"
+#include "test/core/util/port.h"
+
+/* This test does a sanity check that grpc_socket_mutator's
+ * are used by servers. It's meant to protect code and end-to-end
+ * tests that rely on this functionality but which live outside
+ * of the grpc github repo. */
+
+namespace grpc {
+namespace {
+
+bool mock_socket_mutator_mutate_fd(int, grpc_socket_mutator*);
+int mock_socket_mutator_compare(grpc_socket_mutator*, grpc_socket_mutator*);
+void mock_socket_mutator_destroy(grpc_socket_mutator*);
+
+const grpc_socket_mutator_vtable mock_socket_mutator_vtable = {
+ mock_socket_mutator_mutate_fd,
+ mock_socket_mutator_compare,
+ mock_socket_mutator_destroy,
+};
+
+class MockSocketMutator : public grpc_socket_mutator {
+ public:
+ MockSocketMutator() : mutate_fd_call_count_(0) {
+ grpc_socket_mutator_init(this, &mock_socket_mutator_vtable);
+ }
+ int mutate_fd_call_count_;
+};
+
+bool mock_socket_mutator_mutate_fd(int fd, grpc_socket_mutator* m) {
+ MockSocketMutator* s = reinterpret_cast<MockSocketMutator*>(m);
+ s->mutate_fd_call_count_++;
+ return true;
+}
+
+int mock_socket_mutator_compare(grpc_socket_mutator* a,
+ grpc_socket_mutator* b) {
+ return (uintptr_t)a - (uintptr_t)b;
+}
+
+void mock_socket_mutator_destroy(grpc_socket_mutator* m) {
+ MockSocketMutator* s = reinterpret_cast<MockSocketMutator*>(m);
+ delete s;
+}
+
+class MockSocketMutatorServerBuilderOption : public grpc::ServerBuilderOption {
+ public:
+ MockSocketMutatorServerBuilderOption(MockSocketMutator* mock_socket_mutator)
+ : mock_socket_mutator_(mock_socket_mutator) {}
+
+ void UpdateArguments(ChannelArguments* args) override {
+ args->SetSocketMutator(mock_socket_mutator_);
+ }
+
+ void UpdatePlugins(
+ std::vector<std::unique_ptr<ServerBuilderPlugin>>*) override{};
+
+ MockSocketMutator* mock_socket_mutator_;
+};
+
+TEST(ServerBuilderWithSocketMutatorTest, CreateServerWithSocketMutator) {
+ auto address = "localhost:" + std::to_string(grpc_pick_unused_port_or_die());
+ auto mock_socket_mutator = new MockSocketMutator();
+ std::unique_ptr<grpc::ServerBuilderOption> mock_socket_mutator_builder_option(
+ new MockSocketMutatorServerBuilderOption(mock_socket_mutator));
+ testing::EchoTestService::Service echo_service;
+ EXPECT_EQ(mock_socket_mutator->mutate_fd_call_count_, 0);
+ ServerBuilder builder;
+ builder.RegisterService(&echo_service);
+ builder.AddListeningPort(address, InsecureServerCredentials());
+ builder.SetOption(std::move(mock_socket_mutator_builder_option));
+ std::unique_ptr<grpc::Server> server(builder.BuildAndStart());
+ EXPECT_NE(server, nullptr);
+ // Only assert that the socket mutator was used.
+ EXPECT_GE(mock_socket_mutator->mutate_fd_call_count_, 1);
+ server->Shutdown();
+}
+
+} // namespace
+} // namespace grpc
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ grpc_init();
+ int ret = RUN_ALL_TESTS();
+ grpc_shutdown();
+ return ret;
+}
diff --git a/test/cpp/util/BUILD b/test/cpp/util/BUILD
index f53bc7e..b1153d2 100644
--- a/test/cpp/util/BUILD
+++ b/test/cpp/util/BUILD
@@ -112,7 +112,7 @@
],
deps = [
"//:grpc++_unsecure",
- "//test/core/util:grpc_test_util",
+ "//test/core/util:grpc_test_util_unsecure",
],
)
diff --git a/test/cpp/util/byte_buffer_test.cc b/test/cpp/util/byte_buffer_test.cc
index 605ef15..47a5b7f 100644
--- a/test/cpp/util/byte_buffer_test.cc
+++ b/test/cpp/util/byte_buffer_test.cc
@@ -16,7 +16,8 @@
*
*/
-#include <grpcpp/support/byte_buffer.h>
+#include <grpc++/support/byte_buffer.h>
+#include <grpcpp/impl/grpc_library.h>
#include <cstring>
#include <vector>
@@ -27,6 +28,9 @@
#include <gtest/gtest.h>
namespace grpc {
+
+static internal::GrpcLibraryInitializer g_gli_initializer;
+
namespace {
const char* kContent1 = "hello xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
diff --git a/test/cpp/util/create_test_channel.cc b/test/cpp/util/create_test_channel.cc
index 1047d44..0bcd4db 100644
--- a/test/cpp/util/create_test_channel.cc
+++ b/test/cpp/util/create_test_channel.cc
@@ -107,37 +107,37 @@
std::shared_ptr<Channel> CreateTestChannel(
const grpc::string& server, const grpc::string& override_hostname,
- bool enable_ssl, bool use_prod_roots,
+ testing::transport_security security_type, bool use_prod_roots,
const std::shared_ptr<CallCredentials>& creds,
const ChannelArguments& args) {
- grpc::string type;
- if (enable_ssl) {
- type = testing::kTlsCredentialsType;
- }
-
+ grpc::string type =
+ security_type == testing::ALTS
+ ? testing::kAltsCredentialsType
+ : (security_type == testing::TLS ? testing::kTlsCredentialsType
+ : testing::kInsecureCredentialsType);
return CreateTestChannel(server, type, override_hostname, use_prod_roots,
creds, args);
}
std::shared_ptr<Channel> CreateTestChannel(
const grpc::string& server, const grpc::string& override_hostname,
- bool enable_ssl, bool use_prod_roots,
+ testing::transport_security security_type, bool use_prod_roots,
const std::shared_ptr<CallCredentials>& creds) {
- return CreateTestChannel(server, override_hostname, enable_ssl,
+ return CreateTestChannel(server, override_hostname, security_type,
use_prod_roots, creds, ChannelArguments());
}
std::shared_ptr<Channel> CreateTestChannel(
const grpc::string& server, const grpc::string& override_hostname,
- bool enable_ssl, bool use_prod_roots) {
- return CreateTestChannel(server, override_hostname, enable_ssl,
+ testing::transport_security security_type, bool use_prod_roots) {
+ return CreateTestChannel(server, override_hostname, security_type,
use_prod_roots, std::shared_ptr<CallCredentials>());
}
// Shortcut for end2end and interop tests.
-std::shared_ptr<Channel> CreateTestChannel(const grpc::string& server,
- bool enable_ssl) {
- return CreateTestChannel(server, "foo.test.google.fr", enable_ssl, false);
+std::shared_ptr<Channel> CreateTestChannel(
+ const grpc::string& server, testing::transport_security security_type) {
+ return CreateTestChannel(server, "foo.test.google.fr", security_type, false);
}
std::shared_ptr<Channel> CreateTestChannel(
diff --git a/test/cpp/util/create_test_channel.h b/test/cpp/util/create_test_channel.h
index ddaa99f..c615fb7 100644
--- a/test/cpp/util/create_test_channel.h
+++ b/test/cpp/util/create_test_channel.h
@@ -26,21 +26,27 @@
namespace grpc {
class Channel;
-std::shared_ptr<Channel> CreateTestChannel(const grpc::string& server,
- bool enable_ssl);
+namespace testing {
+
+typedef enum { INSECURE = 0, TLS, ALTS } transport_security;
+
+} // namespace testing
+
+std::shared_ptr<Channel> CreateTestChannel(
+ const grpc::string& server, testing::transport_security security_type);
std::shared_ptr<Channel> CreateTestChannel(
const grpc::string& server, const grpc::string& override_hostname,
- bool enable_ssl, bool use_prod_roots);
+ testing::transport_security security_type, bool use_prod_roots);
std::shared_ptr<Channel> CreateTestChannel(
const grpc::string& server, const grpc::string& override_hostname,
- bool enable_ssl, bool use_prod_roots,
+ testing::transport_security security_type, bool use_prod_roots,
const std::shared_ptr<CallCredentials>& creds);
std::shared_ptr<Channel> CreateTestChannel(
const grpc::string& server, const grpc::string& override_hostname,
- bool enable_ssl, bool use_prod_roots,
+ testing::transport_security security_type, bool use_prod_roots,
const std::shared_ptr<CallCredentials>& creds,
const ChannelArguments& args);
diff --git a/test/cpp/util/grpc_tool_test.cc b/test/cpp/util/grpc_tool_test.cc
index 9f7fec5..6574d1b 100644
--- a/test/cpp/util/grpc_tool_test.cc
+++ b/test/cpp/util/grpc_tool_test.cc
@@ -22,6 +22,7 @@
#include <gflags/gflags.h>
#include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
#include <grpcpp/channel.h>
#include <grpcpp/client_context.h>
#include <grpcpp/create_channel.h>
@@ -738,6 +739,8 @@
FLAGS_metadata = "";
FLAGS_protofiles = "";
+
+ gpr_free(test_srcdir);
}
} // namespace testing
diff --git a/test/cpp/util/slice_test.cc b/test/cpp/util/slice_test.cc
index 8e06062..dc19100 100644
--- a/test/cpp/util/slice_test.cc
+++ b/test/cpp/util/slice_test.cc
@@ -16,13 +16,17 @@
*
*/
-#include <grpcpp/support/slice.h>
+#include <grpc++/support/slice.h>
+#include <grpcpp/impl/grpc_library.h>
#include <grpc/grpc.h>
#include <grpc/slice.h>
#include <gtest/gtest.h>
namespace grpc {
+
+static internal::GrpcLibraryInitializer g_gli_initializer;
+
namespace {
const char* kContent = "hello xxxxxxxxxxxxxxxxxxxx world";
diff --git a/test/cpp/util/test_credentials_provider.cc b/test/cpp/util/test_credentials_provider.cc
index 7656100..c8b0ac7 100644
--- a/test/cpp/util/test_credentials_provider.cc
+++ b/test/cpp/util/test_credentials_provider.cc
@@ -56,6 +56,9 @@
const grpc::string& type, ChannelArguments* args) override {
if (type == grpc::testing::kInsecureCredentialsType) {
return InsecureChannelCredentials();
+ } else if (type == grpc::testing::kAltsCredentialsType) {
+ grpc::experimental::AltsCredentialsOptions alts_opts;
+ return grpc::experimental::AltsCredentials(alts_opts);
} else if (type == grpc::testing::kTlsCredentialsType) {
SslCredentialsOptions ssl_opts = {test_root_cert, "", ""};
args->SetSslTargetNameOverride("foo.test.google.fr");
@@ -77,6 +80,9 @@
const grpc::string& type) override {
if (type == grpc::testing::kInsecureCredentialsType) {
return InsecureServerCredentials();
+ } else if (type == grpc::testing::kAltsCredentialsType) {
+ grpc::experimental::AltsServerCredentialsOptions alts_opts;
+ return grpc::experimental::AltsServerCredentials(alts_opts);
} else if (type == grpc::testing::kTlsCredentialsType) {
SslServerCredentialsOptions::PemKeyCertPair pkcp = {test_server1_key,
test_server1_cert};
diff --git a/test/cpp/util/test_credentials_provider.h b/test/cpp/util/test_credentials_provider.h
index f489a2c..b1d69e8 100644
--- a/test/cpp/util/test_credentials_provider.h
+++ b/test/cpp/util/test_credentials_provider.h
@@ -29,10 +29,10 @@
namespace testing {
const char kInsecureCredentialsType[] = "INSECURE_CREDENTIALS";
-
// For real credentials, like tls/ssl, this name should match the AuthContext
// property "transport_security_type".
const char kTlsCredentialsType[] = "ssl";
+const char kAltsCredentialsType[] = "alts";
// Provide test credentials of a particular type.
class CredentialTypeProvider {
diff --git a/test/distrib/cpp/run_distrib_test_cmake_as_externalproject.bat b/test/distrib/cpp/run_distrib_test_cmake_as_externalproject.bat
new file mode 100644
index 0000000..6f4d581
--- /dev/null
+++ b/test/distrib/cpp/run_distrib_test_cmake_as_externalproject.bat
@@ -0,0 +1,41 @@
+@rem Copyright 2016 gRPC authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem http://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+
+@rem enter this directory
+cd /d %~dp0\..\..\..
+
+@rem TODO(jtattermusch): Kokoro has pre-installed protoc.exe in C:\Program Files\ProtoC and that directory
+@rem is on PATH. To avoid picking up the older version protoc.exe, we change the path to something non-existent.
+set PATH=%PATH:ProtoC=DontPickupProtoC%
+
+@rem Download OpenSSL-Win32 originally installed from https://slproweb.com/products/Win32OpenSSL.html
+powershell -Command "(New-Object Net.WebClient).DownloadFile('https://storage.googleapis.com/grpc-testing.appspot.com/OpenSSL-Win32-1_1_0g.zip', 'OpenSSL-Win32.zip')"
+powershell -Command "Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::ExtractToDirectory('OpenSSL-Win32.zip', '.');"
+
+@rem set absolute path to OpenSSL with forward slashes
+set OPENSSL_DIR=%cd:\=/%/OpenSSL-Win32
+
+@rem Build helloworld example using cmake
+@rem Use non-standard build directory to avoid too long filenames
+mkdir example_build
+cd example_build
+cmake -DOPENSSL_ROOT_DIR=%OPENSSL_DIR% ../examples/cpp/helloworld/cmake_externalproject || goto :error
+cmake --build . --config Release || goto :error
+cd ..
+
+goto :EOF
+
+:error
+echo Failed!
+exit /b %errorlevel%
diff --git a/test/distrib/cpp/run_distrib_test_cmake_as_externalproject.sh b/test/distrib/cpp/run_distrib_test_cmake_as_externalproject.sh
new file mode 100755
index 0000000..163527f
--- /dev/null
+++ b/test/distrib/cpp/run_distrib_test_cmake_as_externalproject.sh
@@ -0,0 +1,41 @@
+#!/bin/bash
+# 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.
+
+set -ex
+
+cd "$(dirname "$0")/../../.."
+
+echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list
+apt-get update
+apt-get install -t jessie-backports -y libssl-dev
+
+# To increase the confidence that gRPC installation works without depending on
+# too many submodules unnecessarily, just wipe out contents of most submodules
+# before starting the test.
+rm -r third_party/abseil-cpp/* || true
+rm -r third_party/benchmark/* || true
+rm -r third_party/bloaty/* || true
+rm -r third_party/boringssl/* || true
+rm -r third_party/boringssl-with-bazel/* || true
+rm -r third_party/gflags/* || true
+rm -r third_party/googletest/* || true
+
+# Build helloworld example using cmake superbuild
+cd examples/cpp/helloworld/cmake_externalproject
+mkdir -p cmake/build
+cd cmake/build
+cmake ../..
+make
+
diff --git a/test/distrib/cpp/run_distrib_test_cmake_as_submodule.sh b/test/distrib/cpp/run_distrib_test_cmake_as_submodule.sh
new file mode 100755
index 0000000..defc63e
--- /dev/null
+++ b/test/distrib/cpp/run_distrib_test_cmake_as_submodule.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+# 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.
+
+set -ex
+
+cd "$(dirname "$0")/../../.."
+
+# Build helloworld example using cmake, including grpc with "add_subdirectory"
+cd examples/cpp/helloworld
+mkdir -p cmake/build
+cd cmake/build
+cmake -DGRPC_AS_SUBMODULE=ON ../..
+make
diff --git a/test/distrib/python/run_binary_distrib_test.sh b/test/distrib/python/run_binary_distrib_test.sh
new file mode 100755
index 0000000..061d041
--- /dev/null
+++ b/test/distrib/python/run_binary_distrib_test.sh
@@ -0,0 +1,18 @@
+#!/usr/bin/env bash
+# Copyright 2018 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.
+
+set -ex
+
+"$(dirname "$0")/test_packages.sh" binary
diff --git a/test/distrib/python/run_distrib_test.sh b/test/distrib/python/run_distrib_test.sh
deleted file mode 100755
index a855ae3..0000000
--- a/test/distrib/python/run_distrib_test.sh
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/usr/bin/env bash
-# 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.
-
-set -ex
-
-cd "$(dirname "$0")"
-
-shopt -s nullglob
-
-# Pick up the source dist archive whatever its version is
-SDIST_ARCHIVES=("$EXTERNAL_GIT_ROOT"/input_artifacts/grpcio-*.tar.gz)
-BDIST_ARCHIVES=("$EXTERNAL_GIT_ROOT"/input_artifacts/grpcio-*.whl)
-TOOLS_SDIST_ARCHIVES=("$EXTERNAL_GIT_ROOT"/input_artifacts/grpcio_tools-*.tar.gz)
-TOOLS_BDIST_ARCHIVES=("$EXTERNAL_GIT_ROOT"/input_artifacts/grpcio_tools-*.whl)
-
-function make_virtualenv() {
- virtualenv "$1"
- "$1/bin/python" -m pip install --upgrade six pip
- "$1/bin/python" -m pip install cython
-}
-
-function at_least_one_installs() {
- for file in "$@"; do
- if python -m pip install "$file"; then
- return 0
- fi
- done
- return -1
-}
-
-make_virtualenv bdist_test
-make_virtualenv sdist_test
-
-#
-# Install our distributions in order of dependencies
-#
-
-(source bdist_test/bin/activate && at_least_one_installs "${BDIST_ARCHIVES[@]}")
-(source bdist_test/bin/activate && at_least_one_installs "${TOOLS_BDIST_ARCHIVES[@]}")
-
-(source sdist_test/bin/activate && at_least_one_installs "${SDIST_ARCHIVES[@]}")
-(source sdist_test/bin/activate && at_least_one_installs "${TOOLS_SDIST_ARCHIVES[@]}")
-
-#
-# Test our distributions
-#
-
-# TODO(jtattermusch): add a .proto file to the distribtest, generate python
-# code from it and then use the generated code from distribtest.py
-(source bdist_test/bin/activate && python -m grpc.tools.protoc --help)
-(source sdist_test/bin/activate && python -m grpc.tools.protoc --help)
-
-(source bdist_test/bin/activate && python distribtest.py)
-(source sdist_test/bin/activate && python distribtest.py)
diff --git a/test/distrib/python/run_source_distrib_test.sh b/test/distrib/python/run_source_distrib_test.sh
new file mode 100755
index 0000000..f667674
--- /dev/null
+++ b/test/distrib/python/run_source_distrib_test.sh
@@ -0,0 +1,18 @@
+#!/usr/bin/env bash
+# Copyright 2018 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.
+
+set -ex
+
+"$(dirname "$0")/test_packages.sh" source
diff --git a/test/distrib/python/test_packages.sh b/test/distrib/python/test_packages.sh
new file mode 100755
index 0000000..6bf49d4
--- /dev/null
+++ b/test/distrib/python/test_packages.sh
@@ -0,0 +1,73 @@
+#!/usr/bin/env bash
+# Copyright 2018 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.
+
+set -ex
+
+cd "$(dirname "$0")"
+
+shopt -s nullglob
+
+if [[ "$1" == "binary" ]]
+then
+ echo "Testing Python binary distribution"
+ ARCHIVES=("$EXTERNAL_GIT_ROOT"/input_artifacts/grpcio-[0-9]*.whl)
+ TOOLS_ARCHIVES=("$EXTERNAL_GIT_ROOT"/input_artifacts/grpcio_tools-[0-9]*.whl)
+else
+ echo "Testing Python source distribution"
+ ARCHIVES=("$EXTERNAL_GIT_ROOT"/input_artifacts/grpcio-[0-9]*.tar.gz)
+ TOOLS_ARCHIVES=("$EXTERNAL_GIT_ROOT"/input_artifacts/grpcio-tools-[0-9]*.tar.gz)
+ HEALTH_ARCHIVES=("$EXTERNAL_GIT_ROOT"/input_artifacts/grpcio-health-checking-[0-9]*.tar.gz)
+ REFLECTION_ARCHIVES=("$EXTERNAL_GIT_ROOT"/input_artifacts/grpcio-reflection-[0-9]*.tar.gz)
+fi
+
+VIRTUAL_ENV=$(mktemp -d)
+virtualenv "$VIRTUAL_ENV"
+PYTHON=$VIRTUAL_ENV/bin/python
+"$PYTHON" -m pip install --upgrade six pip
+
+function at_least_one_installs() {
+ for file in "$@"; do
+ if "$PYTHON" -m pip install "$file"; then
+ return 0
+ fi
+ done
+ return 1
+}
+
+
+#
+# Install our distributions in order of dependencies
+#
+
+at_least_one_installs "${ARCHIVES[@]}"
+at_least_one_installs "${TOOLS_ARCHIVES[@]}"
+
+if [[ "$1" == "source" ]]
+then
+ echo "Testing Python health and reflection packages"
+ at_least_one_installs "${HEALTH_ARCHIVES[@]}"
+ at_least_one_installs "${REFLECTION_ARCHIVES[@]}"
+fi
+
+
+#
+# Test our distributions
+#
+
+# TODO(jtattermusch): add a .proto file to the distribtest, generate python
+# code from it and then use the generated code from distribtest.py
+"$PYTHON" -m grpc.tools.protoc --help
+
+"$PYTHON" distribtest.py
diff --git a/test/distrib/ruby/run_distrib_test.sh b/test/distrib/ruby/run_distrib_test.sh
index 99fb873..cb2eb1f 100755
--- a/test/distrib/ruby/run_distrib_test.sh
+++ b/test/distrib/ruby/run_distrib_test.sh
@@ -35,3 +35,24 @@
bundle install
bundle exec ./distribtest.rb
+
+# Attempt to repro https://github.com/google/protobuf/issues/4210.
+# TODO: This sanity check only works for linux-based distrib tests and for
+# binary gRPC packages. It will need to be ran conditionally if this test script is
+# used for other types of distrib tests.
+INSTALLATION_DIR="$(gem env | grep '\- INSTALLATION DIRECTORY' | awk '{ print $4 }')"
+if [[ "$(find "$INSTALLATION_DIR" -name 'grpc_c.so' | wc -l)" == 0 ]]; then
+ echo "Sanity check failed. The gRPC package is not installed in $INSTALLATION_DIR."
+ exit 1
+fi
+LIBRUBY_DEPENDENCY_EXISTS="$(find "$INSTALLATION_DIR" -name 'grpc_c.so' -exec ldd {} \; | grep -c 'libruby')" || true
+if [[ "$LIBRUBY_DEPENDENCY_EXISTS" != 0 ]]; then
+ echo "A grpc_c.so file in this binary gRPC package is dynamically linked to libruby."
+fi
+DEPENDENCY_NOT_FOUND="$(find "$INSTALLATION_DIR" -name 'grpc_c.so' -exec ldd {} \; | grep -c 'not found')" || true
+if [[ "$DEPENDENCY_NOT_FOUND" != 0 ]]; then
+ echo "A grpc_c.so file in this binary gRPC package has an non-portable dependency."
+fi
+if [ "$LIBRUBY_DEPENDENCY_EXISTS" != 0 ] || [ "$DEPENDENCY_NOT_FOUND" != 0 ]; then
+ exit 1
+fi
diff --git a/third_party/address_sorting/LICENSE b/third_party/address_sorting/LICENSE
index db4b5a5..824d542 100644
--- a/third_party/address_sorting/LICENSE
+++ b/third_party/address_sorting/LICENSE
@@ -1,262 +1,3 @@
- Copyright (c) 2014, ARM Limited
- All rights Reserved.
- Copyright (c) 2014, Linaro Ltd.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of the company nor the names of its contributors
- may be used to endorse or promote products derived from this
- software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
- Copyright (c) 2014, Linaro Limited
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of the Linaro nor the
- names of its contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
- Copyright (c) 1993 John Brezak
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- 3. The name of the author may be used to endorse or promote products
- derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
-IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
-INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
- Copyright (c) 2009-2013 The Linux Foundation. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of The Linux Foundation nor the names of its contributors may
- be used to endorse or promote products derived from this software
- without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-====================================================
-Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
-
-Developed at SunPro, a Sun Microsystems, Inc. business.
-Permission to use, copy, modify, and distribute this
-software is freely granted, provided that this notice
-is preserved.
-
--------------------------------------------------------------------
-
-====================================================
-Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
-
-Developed at SunPro, a Sun Microsystems, Inc. business.
-Permission to use, copy, modify, and distribute this
-software is freely granted, provided that this notice
-is preserved.
-====================================================
-
-Optimized by Bruce D. Evans.
-
--------------------------------------------------------------------
-
-====================================================
-Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
-
-Developed at SunSoft, a Sun Microsystems, Inc. business.
-Permission to use, copy, modify, and distribute this
-software is freely granted, provided that this notice
-is preserved.
-
--------------------------------------------------------------------
-
-====================================================
-Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
-
-Developed at SunSoft, a Sun Microsystems, Inc. business.
-Permission to use, copy, modify, and distribute this
-software is freely granted, provided that this notice
-is preserved.
-====================================================
-
-Optimized by Bruce D. Evans.
-
--------------------------------------------------------------------
-
-====================================================
-Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
-Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans.
-
-Developed at SunSoft, a Sun Microsystems, Inc. business.
-Permission to use, copy, modify, and distribute this
-software is freely granted, provided that this notice
-is preserved.
-
--------------------------------------------------------------------
-
-====================================================
-Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
-Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans.
-
-Developed at SunSoft, a Sun Microsystems, Inc. business.
-Permission to use, copy, modify, and distribute this
-software is freely granted, provided that this notice
-is preserved.
-====================================================
-
-Optimized by Bruce D. Evans.
-
--------------------------------------------------------------------
-
-====================================================
-Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
-Copyright (c) 2009-2011, Bruce D. Evans, Steven G. Kargl, David Schultz.
-
-Developed at SunPro, a Sun Microsystems, Inc. business.
-Permission to use, copy, modify, and distribute this
-software is freely granted, provided that this notice
-is preserved.
-====================================================
-
-The argument reduction and testing for exceptional cases was
-written by Steven G. Kargl with input from Bruce D. Evans
-and David A. Schultz.
-
--------------------------------------------------------------------
-
-====================================================
-Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved.
-
-Permission to use, copy, modify, and distribute this
-software is freely granted, provided that this notice
-is preserved.
-
--------------------------------------------------------------------
-
-====================================================
-Copyright 2004 Sun Microsystems, Inc. All Rights Reserved.
-
-Permission to use, copy, modify, and distribute this
-software is freely granted, provided that this notice
-is preserved.
-
--------------------------------------------------------------------
-
-====================================================
-Copyright 2004 Sun Microsystems, Inc. All Rights Reserved.
-Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans.
-
-Permission to use, copy, modify, and distribute this
-software is freely granted, provided that this notice
-is preserved.
-
--------------------------------------------------------------------
-
-Based on the UCB version with the ID appearing below.
-This is ANSIish only when "multibyte character == plain character".
-
-Copyright (c) 1989, 1993
- The Regents of the University of California. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
All rights reserved.
@@ -283,5819 +24,3 @@
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (C) 2004, 2005, 2008 Internet Systems Consortium, Inc. ("ISC")
-Copyright (C) 1995-1999, 2001, 2003 Internet Software Consortium.
-
-Permission to use, copy, modify, and/or distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-
--------------------------------------------------------------------
-
-Copyright (C) 2004, 2005, 2008 Internet Systems Consortium, Inc. ("ISC")
-Copyright (C) 1997-2001 Internet Software Consortium.
-
-Permission to use, copy, modify, and/or distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-
--------------------------------------------------------------------
-
-Copyright (C) 2006 The Android Open Source Project
-
-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.
-
--------------------------------------------------------------------
-
-Copyright (C) 2006 The Android Open Source Project
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the
- distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
-OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
-AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (C) 2007 The Android Open Source Project
-
-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.
-
--------------------------------------------------------------------
-
-Copyright (C) 2007 The Android Open Source Project
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the
- distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
-OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
-AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (C) 2008 The Android Open Source Project
-
-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.
-
--------------------------------------------------------------------
-
-Copyright (C) 2008 The Android Open Source Project
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the
- distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
-OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
-AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (C) 2008 The Android Open Source Project
-All rights reserved.
-Copyright (c) 2013-2014, NVIDIA Corporation. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the
- distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
-OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
-AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (C) 2009 The Android Open Source Project
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the
- distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
-OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
-AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (C) 2010 The Android Open Source Project
-
-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.
-
--------------------------------------------------------------------
-
-Copyright (C) 2010 The Android Open Source Project
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the
- distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
-OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
-AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (C) 2010 The Android Open Source Project
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (C) 2010 The Android Open Source Project
-Copyright (c) 2008 ARM Ltd
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. The name of the company may not be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
-THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-Android adaptation and tweak by Jim Huang <jserv@0xlab.org>.
-
--------------------------------------------------------------------
-
-Copyright (C) 2011 The Android Open Source Project
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the
- distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
-OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
-AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (C) 2012 The Android Open Source Project
-
-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.
-
--------------------------------------------------------------------
-
-Copyright (C) 2012 The Android Open Source Project
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the
- distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
-OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
-AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (C) 2013 Pietro Cerutti <gahr@FreeBSD.org>
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (C) 2013 The Android Open Source Project
-
-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.
-
--------------------------------------------------------------------
-
-Copyright (C) 2013 The Android Open Source Project
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the
- distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
-OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
-AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (C) 2013 The Android Open Source Project
-All rights reserved.
-Copyright (c) 2013-2014 NVIDIA Corporation. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the
- distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
-OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
-AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (C) 2013 The Android Open Source Project
-Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the
- distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
-OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
-AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (C) 2014 The Android Open Source Project
-
-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.
-
--------------------------------------------------------------------
-
-Copyright (C) 2014 The Android Open Source Project
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the
- distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
-OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
-AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (C) 2014 The Android Open Source Project
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (C) 2015 The Android Open Source Project
-
-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.
-
--------------------------------------------------------------------
-
-Copyright (C) 2015 The Android Open Source Project
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the
- distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
-OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
-AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (C) 2016 The Android Open Source Project
-
-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.
-
--------------------------------------------------------------------
-
-Copyright (C) 2016 The Android Open Source Project
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the
- distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
-OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
-AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (C) 2017 The Android Open Source Project
-
-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.
-
--------------------------------------------------------------------
-
-Copyright (C) 2017 The Android Open Source Project
-All rights reserved.
-
-Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the
- distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
-OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
-AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (C) 2017 The Android Open Source Project
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the
- distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
-OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
-AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1980, 1983, 1988, 1993
- The Regents of the University of California. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. All advertising materials mentioning features or use of this software
- must display the following acknowledgement:
- This product includes software developed by the University of
- California, Berkeley and its contributors.
-4. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
-
-Portions Copyright (c) 1993 by Digital Equipment Corporation.
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies, and that
-the name of Digital Equipment Corporation not be used in advertising or
-publicity pertaining to distribution of the document or software without
-specific, written prior permission.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
-WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
-OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
-CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
-DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
-PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
-ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1982, 1986, 1993
- The Regents of the University of California. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1982, 1986, 1993
- The Regents of the University of California. All rights reserved.
-(c) UNIX System Laboratories, Inc.
-All or some portions of this file are derived from material licensed
-to the University of California by American Telephone and Telegraph
-Co. or Unix System Laboratories, Inc. and are reproduced herein with
-the permission of UNIX System Laboratories, Inc.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1983, 1987, 1989
- The Regents of the University of California. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1983, 1989
- The Regents of the University of California. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. All advertising materials mentioning features or use of this software
- must display the following acknowledgement:
- This product includes software developed by the University of
- California, Berkeley and its contributors.
-4. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1983, 1989, 1993
- The Regents of the University of California. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1983, 1993
- The Regents of the University of California. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1985
- The Regents of the University of California. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. All advertising materials mentioning features or use of this software
- must display the following acknowledgement:
- This product includes software developed by the University of
- California, Berkeley and its contributors.
-4. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1985 Regents of the University of California.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1985, 1988, 1993
- The Regents of the University of California. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
-Portions Copyright (c) 1993 by Digital Equipment Corporation.
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies, and that
-the name of Digital Equipment Corporation not be used in advertising or
-publicity pertaining to distribution of the document or software without
-specific, written prior permission.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
-WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
-OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
-CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
-DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
-PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
-ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1985, 1989, 1993
- The Regents of the University of California. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. All advertising materials mentioning features or use of this software
- must display the following acknowledgement:
- This product includes software developed by the University of
- California, Berkeley and its contributors.
-4. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1985, 1993
- The Regents of the University of California. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. All advertising materials mentioning features or use of this software
- must display the following acknowledgement:
- This product includes software developed by the University of
- California, Berkeley and its contributors.
-4. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1985, 1993
- The Regents of the University of California. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. All advertising materials mentioning features or use of this software
- must display the following acknowledgement:
- This product includes software developed by the University of
- California, Berkeley and its contributors.
-4. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1985, 1993
- The Regents of the University of California. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1987 Regents of the University of California.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1987, 1993
- The Regents of the University of California. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. All advertising materials mentioning features or use of this software
- must display the following acknowledgement:
- This product includes software developed by the University of
- California, Berkeley and its contributors.
-4. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1987, 1993
- The Regents of the University of California. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1988 Regents of the University of California.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1988 The Regents of the University of California.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1988, 1993
- The Regents of the University of California. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. All advertising materials mentioning features or use of this software
- must display the following acknowledgement:
- This product includes software developed by the University of
- California, Berkeley and its contributors.
-4. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1988, 1993
- The Regents of the University of California. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. All advertising materials mentioning features or use of this software
- must display the following acknowledgement:
- This product includes software developed by the University of
- California, Berkeley and its contributors.
-4. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1988, 1993
- The Regents of the University of California. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1988, 1993
- The Regents of the University of California. All rights reserved.
-
-This code is derived from software written by Ken Arnold and
-published in UNIX Review, Vol. 6, No. 8.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1989 The Regents of the University of California.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1989 The Regents of the University of California.
-All rights reserved.
-(c) UNIX System Laboratories, Inc.
-All or some portions of this file are derived from material licensed
-to the University of California by American Telephone and Telegraph
-Co. or Unix System Laboratories, Inc. and are reproduced herein with
-the permission of UNIX System Laboratories, Inc.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1989, 1993
- The Regents of the University of California. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1989, 1993
- The Regents of the University of California. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-4. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1989, 1993
- The Regents of the University of California. All rights reserved.
-
-This code is derived from software contributed to Berkeley by
-Guido van Rossum.
-
-Copyright (c) 2011 The FreeBSD Foundation
-All rights reserved.
-Portions of this software were developed by David Chisnall
-under sponsorship from the FreeBSD Foundation.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1989, 1993
- The Regents of the University of California. All rights reserved.
-
-This code is derived from software contributed to Berkeley by
-Guido van Rossum.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1989, 1993
- The Regents of the University of California. All rights reserved.
-
-This code is derived from software contributed to Berkeley by
-Roger L. Snyder.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1989, 1993
- The Regents of the University of California. All rights reserved.
-(c) UNIX System Laboratories, Inc.
-All or some portions of this file are derived from material licensed
-to the University of California by American Telephone and Telegraph
-Co. or Unix System Laboratories, Inc. and are reproduced herein with
-the permission of UNIX System Laboratories, Inc.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1990 Regents of the University of California.
-All rights reserved.
-
-This code is derived from software contributed to Berkeley by
-Chris Torek.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1990 The Regents of the University of California.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1990 The Regents of the University of California.
-All rights reserved.
-
-This code is derived from software contributed to Berkeley by
-Chris Torek.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1990 The Regents of the University of California.
-All rights reserved.
-
-This code is derived from software contributed to Berkeley by
-William Jolitz.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1990, 1993
- The Regents of the University of California. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1990, 1993
- The Regents of the University of California. All rights reserved.
-
-This code is derived from software contributed to Berkeley by
-Chris Torek.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1990, 1993
- The Regents of the University of California. All rights reserved.
-
-This code is derived from software contributed to Berkeley by
-Donn Seeley at UUNET Technologies, Inc.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1990, 1993
- The Regents of the University of California. All rights reserved.
-
-This code is derived from software contributed to Berkeley by
-Donn Seeley at UUNET Technologies, Inc.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-4. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1990, 1993
- The Regents of the University of California. All rights reserved.
-(c) UNIX System Laboratories, Inc.
-All or some portions of this file are derived from material licensed
-to the University of California by American Telephone and Telegraph
-Co. or Unix System Laboratories, Inc. and are reproduced herein with
-the permission of UNIX System Laboratories, Inc.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1990, 1993, 1994
- The Regents of the University of California. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1990, 1993, 1994
- The Regents of the University of California. All rights reserved.
-
-This code is derived from software contributed to Berkeley by
-Chris Torek.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1991 The Regents of the University of California.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1991, 1993
- The Regents of the University of California. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1991, 1993
- The Regents of the University of California. All rights reserved.
-
-This code is derived from software contributed to Berkeley by
-Berkeley Software Design, Inc.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1991, 1993
- The Regents of the University of California. All rights reserved.
-(c) UNIX System Laboratories, Inc.
-All or some portions of this file are derived from material licensed
-to the University of California by American Telephone and Telegraph
-Co. or Unix System Laboratories, Inc. and are reproduced herein with
-the permission of UNIX System Laboratories, Inc.
-
-This code is derived from software contributed to Berkeley by
-Hugh Smith at The University of Guelph.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1991, 1993, 1995,
- The Regents of the University of California. All rights reserved.
-
-This code is derived from software contributed to Berkeley by
-Havard Eidnes.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1992 Henry Spencer.
-Copyright (c) 1992, 1993
- The Regents of the University of California. All rights reserved.
-
-This code is derived from software contributed to Berkeley by
-Henry Spencer of the University of Toronto.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1992 The Regents of the University of California.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1992, 1993
- The Regents of the University of California. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. All advertising materials mentioning features or use of this software
- must display the following acknowledgement:
- This product includes software developed by the University of
- California, Berkeley and its contributors.
-4. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1992, 1993
- The Regents of the University of California. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1992, 1993
- The Regents of the University of California. All rights reserved.
-
-This code is derived from software contributed to Berkeley by
-Ralph Campbell.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1992, 1993
- The Regents of the University of California. All rights reserved.
-
-This software was developed by the Computer Systems Engineering group
-at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
-contributed to Berkeley.
-
-All advertising materials mentioning features or use of this software
-must display the following acknowledgement:
- This product includes software developed by the University of
- California, Lawrence Berkeley Laboratory.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. All advertising materials mentioning features or use of this software
- must display the following acknowledgement:
- This product includes software developed by the University of
- California, Berkeley and its contributors.
-4. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1992, 1993
- The Regents of the University of California. All rights reserved.
-(c) UNIX System Laboratories, Inc.
-All or some portions of this file are derived from material licensed
-to the University of California by American Telephone and Telegraph
-Co. or Unix System Laboratories, Inc. and are reproduced herein with
-the permission of UNIX System Laboratories, Inc.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1992, 1993, 1994
- The Regents of the University of California. All rights reserved.
-
-This code is derived from software contributed to Berkeley by
-Henry Spencer.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1992, 1993, 1994 Henry Spencer.
-
-This code is derived from software contributed to Berkeley by
-Henry Spencer.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. All advertising materials mentioning features or use of this software
- must display the following acknowledgement:
- This product includes software developed by the University of
- California, Berkeley and its contributors.
-4. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1993
- The Regents of the University of California. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1993 Martin Birgmeier
-All rights reserved.
-
-You may redistribute unmodified or modified versions of this source
-code provided that the above copyright notice and this and the
-following conditions are retained.
-
-This software is provided ``as is'', and comes with no warranties
-of any kind. I shall in no event be liable for anything that happens
-to anyone/anything when using this software.
-
--------------------------------------------------------------------
-
-Copyright (c) 1994 SigmaSoft, Th. Lockert <tholo@sigmasoft.com>
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. The name of the author may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1996 by Internet Software Consortium.
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
-ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
-OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
-CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
-DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
-PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
-ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1996, David Mazieres <dm@uun.org>
-Copyright (c) 2008, Damien Miller <djm@openbsd.org>
-Copyright (c) 2013, Markus Friedl <markus@openbsd.org>
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1996, David Mazieres <dm@uun.org>
-Copyright (c) 2008, Damien Miller <djm@openbsd.org>
-Copyright (c) 2013, Markus Friedl <markus@openbsd.org>
-Copyright (c) 2014, Theo de Raadt <deraadt@openbsd.org>
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1996-1998, 2008 Theo de Raadt
-Copyright (c) 1997, 2008-2009 Todd C. Miller
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1997 Mark Brinicombe
-Copyright (C) 2010 The Android Open Source Project
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. All advertising materials mentioning features or use of this software
- must display the following acknowledgement:
- This product includes software developed by Mark Brinicombe
-4. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1997 Niklas Hallqvist. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. The name of the author may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
-INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
-THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
-All rights reserved.
-
-This code was contributed to The NetBSD Foundation by Klaus Klein.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. All advertising materials mentioning features or use of this software
- must display the following acknowledgement:
- This product includes software developed by the NetBSD
- Foundation, Inc. and its contributors.
-4. Neither the name of The NetBSD Foundation nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
-``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
-BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1997, 1998, 1999, 2004 The NetBSD Foundation, Inc.
-All rights reserved.
-
-This code is derived from software contributed to The NetBSD Foundation
-by Luke Mewburn.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
-``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
-BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1997, 1998, 1999, 2004 The NetBSD Foundation, Inc.
-All rights reserved.
-
-This code is derived from software contributed to The NetBSD Foundation
-by Luke Mewburn; and by Jason R. Thorpe.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. All advertising materials mentioning features or use of this software
- must display the following acknowledgement:
- This product includes software developed by the NetBSD
- Foundation, Inc. and its contributors.
-4. Neither the name of The NetBSD Foundation nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
-``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
-BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1997, 2005 Todd C. Miller <Todd.Miller@courtesan.com>
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1998 Softweyr LLC. All rights reserved.
-
-strtok_r, from Berkeley strtok
-Oct 13, 1998 by Wes Peters <wes@softweyr.com>
-
-Copyright (c) 1988, 1993
- The Regents of the University of California. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notices, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notices, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY SOFTWEYR LLC, THE REGENTS AND CONTRIBUTORS
-``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SOFTWEYR LLC, THE
-REGENTS, OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1998 The NetBSD Foundation, Inc.
-All rights reserved.
-
-This code is derived from software contributed to The NetBSD Foundation
-by Klaus Klein.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. All advertising materials mentioning features or use of this software
- must display the following acknowledgement:
- This product includes software developed by the NetBSD
- Foundation, Inc. and its contributors.
-4. Neither the name of The NetBSD Foundation nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
-``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
-BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. The name of the author may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
-INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
-THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1998, 2015 Todd C. Miller <Todd.Miller@courtesan.com>
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1999
- David E. O'Brien
-Copyright (c) 1988, 1993
- The Regents of the University of California. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2000 Ben Harris.
-Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the project nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2000 The NetBSD Foundation, Inc.
-All rights reserved.
-
-This code is derived from software contributed to The NetBSD Foundation
-by Dieter Baron and Thomas Klausner.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
-``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
-BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2001 Wasabi Systems, Inc.
-All rights reserved.
-
-Written by Frank van der Linden for Wasabi Systems, Inc.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. All advertising materials mentioning features or use of this software
- must display the following acknowledgement:
- This product includes software developed for the NetBSD Project by
- Wasabi Systems, Inc.
-4. The name of Wasabi Systems, Inc. may not be used to endorse
- or promote products derived from this software without specific prior
- written permission.
-
-THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
-BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2001-2002 Opsycon AB (www.opsycon.se / www.opsycon.com)
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
-OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2001-2002 Opsycon AB (www.opsycon.se / www.opsycon.com)
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of Opsycon AB nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
-OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2001-2011 The FreeBSD Project.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2002 Daniel Hartmeier
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-
- - Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- - Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials provided
- with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2002 The NetBSD Foundation, Inc.
-All rights reserved.
-
-This code is derived from software contributed to The NetBSD Foundation
-by Christos Zoulas.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
-``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
-BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2002 Tim J. Robbins
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2002 Tim J. Robbins.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-Sponsored in part by the Defense Advanced Research Projects
-Agency (DARPA) and Air Force Research Laboratory, Air Force
-Materiel Command, USAF, under agreement number F39502-99-1-0512.
-
--------------------------------------------------------------------
-
-Copyright (c) 2002, 2003 Tim J. Robbins.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2002-2004 Tim J. Robbins
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2002-2004 Tim J. Robbins.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2003 Constantin S. Svintsoff <kostik@iclub.nsu.ru>
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. The names of the authors may not be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2003 Dag-Erling Smørgrav
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer
- in this position and unchanged.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. The name of the author may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2003 David Schultz <das@FreeBSD.ORG>
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2003 Mike Barcroft <mike@FreeBSD.org>
-Copyright (c) 2002 David Schultz <das@FreeBSD.ORG>
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2003 Networks Associates Technology, Inc.
-All rights reserved.
-
-Portions of this software were developed for the FreeBSD Project by
-Jacques A. Vidrine, Safeport Network Services, and Network
-Associates Laboratories, the Security Research Division of Network
-Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035
-("CBOSS"), as part of the DARPA CHATS research program.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2003 Todd C. Miller <Todd.Miller@courtesan.com>
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-Sponsored in part by the Defense Advanced Research Projects
-Agency (DARPA) and Air Force Research Laboratory, Air Force
-Materiel Command, USAF, under agreement number F39502-99-1-0512.
-
--------------------------------------------------------------------
-
-Copyright (c) 2003, 2004 Todd C. Miller <Todd.Miller@courtesan.com>
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-Sponsored in part by the Defense Advanced Research Projects
-Agency (DARPA) and Air Force Research Laboratory, Air Force
-Materiel Command, USAF, under agreement number F39502-99-1-0512.
-
--------------------------------------------------------------------
-
-Copyright (c) 2003, Steven G. Kargl
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice unmodified, this list of conditions, and the following
- disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2004 Stefan Farfeleder
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
-Copyright (c) 1995,1999 by Internet Software Consortium.
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
-ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
-Copyright (c) 1995-1999 by Internet Software Consortium
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
-ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
-Copyright (c) 1995-1999 by Internet Software Consortium.
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
-ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
-Copyright (c) 1996,1999 by Internet Software Consortium.
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
-ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
-Copyright (c) 1996-1999 by Internet Software Consortium
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
-ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
-Copyright (c) 1996-1999 by Internet Software Consortium.
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
-ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
-Copyright (c) 1997,1999 by Internet Software Consortium.
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
-ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
-Copyright (c) 1999 by Internet Software Consortium.
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
-ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
-Portions Copyright (c) 1996-1999 by Internet Software Consortium.
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
-ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2004, 2005 David Schultz <das@FreeBSD.ORG>
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2004-2005 David Schultz <das (at) FreeBSD.ORG>
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2004-2005 David Schultz <das@FreeBSD.ORG>
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2005 Bruce D. Evans and Steven G. Kargl
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice unmodified, this list of conditions, and the following
- disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2005 David Schultz <das@FreeBSD.ORG>
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2005 Tim J. Robbins.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2005 by Internet Systems Consortium, Inc. ("ISC")
-Copyright (c) 1995-1999 by Internet Software Consortium
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
-ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2005-2008 David Schultz <das@FreeBSD.ORG>
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2005-2011 David Schultz <das@FreeBSD.ORG>
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2007 David Schultz
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2007 David Schultz <das@FreeBSD.ORG>
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2007 David Schultz <das@FreeBSD.ORG>
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
-Derived from s_modf.c, which has the following Copyright:
-====================================================
-Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
-
-Developed at SunPro, a Sun Microsystems, Inc. business.
-Permission to use, copy, modify, and distribute this
-software is freely granted, provided that this notice
-is preserved.
-
--------------------------------------------------------------------
-
-Copyright (c) 2007 Steven G. Kargl
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice unmodified, this list of conditions, and the following
- disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2007 The NetBSD Foundation, Inc.
-All rights reserved.
-
-This code is derived from software written by Stephen L. Moshier.
-It is redistributed by the NetBSD Foundation by permission of the author.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
-``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
-BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2007 Todd C. Miller <Todd.Miller@courtesan.com>
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2007-2008 Michael G Schwern
-
-This software originally derived from Paul Sheer's pivotal_gmtime_r.c.
-
-The MIT License:
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2007-2008 Michael G Schwern
-
-This software originally derived from Paul Sheer's pivotal_gmtime_r.c.
-
-The MIT License:
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
-Origin: http://code.google.com/p/y2038
-Modified for Bionic by the Android Open Source Project
-
--------------------------------------------------------------------
-
-Copyright (c) 2007-2008 David Schultz <das@FreeBSD.ORG>
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2007-2013 Bruce D. Evans
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice unmodified, this list of conditions, and the following
- disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2008 David Schultz <das@FreeBSD.ORG>
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2008 Todd C. Miller <millert@openbsd.org>
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2008, Damien Miller <djm@openbsd.org>
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2009 David Schultz <das@FreeBSD.org>
-All rights reserved.
-
-Copyright (c) 2011 The FreeBSD Foundation
-All rights reserved.
-Portions of this software were developed by David Chisnall
-under sponsorship from the FreeBSD Foundation.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2009 David Schultz <das@FreeBSD.org>
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2009 The NetBSD Foundation, Inc.
-
-This code is derived from software contributed to The NetBSD Foundation
-by Roy Marples.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2009-2013 Steven G. Kargl
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice unmodified, this list of conditions, and the following
- disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-Optimized by Bruce D. Evans.
-
--------------------------------------------------------------------
-
-Copyright (c) 2010 The NetBSD Foundation, Inc.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
-``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
-BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2010 Todd C. Miller <Todd.Miller@courtesan.com>
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2010, 2011, 2012, 2013 Intel Corporation
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
-
- * Neither the name of Intel Corporation nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2010, Intel Corporation
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
-
- * Neither the name of Intel Corporation nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2011 David Chisnall
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2011 David Schultz
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice unmodified, this list of conditions, and the following
- disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2011 David Schultz <das@FreeBSD.ORG>
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2011 Ed Schouten <ed@FreeBSD.org>
- David Chisnall <theraven@FreeBSD.org>
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2011 Intel Corporation
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
-
- * Neither the name of Intel Corporation nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2011 Martin Pieuchot <mpi@openbsd.org>
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2011 The Android Open Source Project
-Copyright (c) 2008 ARM Ltd
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. The name of the company may not be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
-THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2011, 2012, 2013 Intel Corporation
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
-
- * Neither the name of Intel Corporation nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2011, Intel Corporation
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
-
- * Neither the name of Intel Corporation nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2011, VMware, Inc.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of the VMware, Inc. nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL VMWARE, INC. OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2012 Stephen Montgomery-Smith <stephen@FreeBSD.ORG>
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2012, Linaro Limited
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of the Linaro nor the
- names of its contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2012, Linaro Limited
- All rights reserved.
- Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of the Linaro nor the
- names of its contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2012-2013, Linaro Limited
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of the Linaro nor the
- names of its contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-
--------------------------------------------------------------------
-
-Copyright (c) 2013
- MIPS Technologies, Inc., California.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the MIPS Technologies, Inc., nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2013 ARM Ltd
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. The name of the company may not be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
-THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2013 Antoine Jacoutot <ajacoutot@openbsd.org>
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2013 The NetBSD Foundation, Inc.
-All rights reserved.
-
-This code is derived from software contributed to The NetBSD Foundation
-by Christos Zoulas.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
-``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
-BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2013, Linaro Limited
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of the Linaro nor the
- names of its contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-
--------------------------------------------------------------------
-
-Copyright (c) 2013-2014, NVIDIA Corporation. All rights reserved.
-Johnny Qiu <joqiu@nvidia.com>
-Shu Zhang <chazhang@nvidia.com>
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials provided
- with the distribution.
- * Neither the name of The Linux Foundation nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2013-2015, Linaro Limited
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of the Linaro nor the
- names of its contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-
--------------------------------------------------------------------
-
-Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org>
-Copyright (c) 2014 Bob Beck <beck@obtuse.com>
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-Emulation of getentropy(2) as documented at:
-http://man.openbsd.org/getentropy.2
-
--------------------------------------------------------------------
-
-Copyright (c) 2014, Intel Corporation
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
-
- * Neither the name of Intel Corporation nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2014, Linaro Limited
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of the Linaro nor the
- names of its contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2015 ARM Ltd
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. The name of the company may not be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
-THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2015 Joerg Sonnenberger <joerg@NetBSD.org>.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the
- distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
-BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
-AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2015 Nuxi, https://nuxi.nl/
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2017 ARM Ltd
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. The name of the company may not be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
-THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2017 Imagination Technologies.
-
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer
- in the documentation and/or other materials provided with
- the distribution.
- * Neither the name of Imagination Technologies nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c)1999 Citrus Project,
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c)2001 Citrus Project,
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c)2003 Citrus Project,
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright 1989 The Regents of the University of California.
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- 3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-
--------------------------------------------------------------------
-
-Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
-Copyright 2008 Damien Miller <djm@openbsd.org>
-All rights reserved.
-
-Theo de Raadt <deraadt@openbsd.org> came up with the idea of using
-such a mathematical system to generate more random (yet non-repeating)
-ids to solve the resolver/named problem. But Niels designed the
-actual system based on the constraints.
-
-Later modified by Damien Miller to wrap the LCG output in a 15-bit
-permutation generator based on a Luby-Rackoff block cipher. This
-ensures the output is non-repeating and preserves the MSB twiddle
-trick, but makes it more resistant to LCG prediction.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-From: @(#)s_ilogb.c 5.1 93/09/24
-====================================================
-Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
-
-Developed at SunPro, a Sun Microsystems, Inc. business.
-Permission to use, copy, modify, and distribute this
-software is freely granted, provided that this notice
-is preserved.
-
--------------------------------------------------------------------
-
-Portions Copyright (C) 2004, 2005, 2008, 2009 Internet Systems Consortium, Inc. ("ISC")
-Portions Copyright (C) 1996-2003 Internet Software Consortium.
-
-Permission to use, copy, modify, and/or distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-
--------------------------------------------------------------------
-
-Portions Copyright (c) 1993 by Digital Equipment Corporation.
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies, and that
-the name of Digital Equipment Corporation not be used in advertising or
-publicity pertaining to distribution of the document or software without
-specific, written prior permission.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
-WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
-OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
-CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
-DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
-PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
-ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
--------------------------------------------------------------------
-
-Portions Copyright (c) 1995 by International Business Machines, Inc.
-
-International Business Machines, Inc. (hereinafter called IBM) grants
-permission under its copyrights to use, copy, modify, and distribute this
-Software with or without fee, provided that the above copyright notice and
-all paragraphs of this notice appear in all copies, and that the name of IBM
-not be used in connection with the marketing of any product incorporating
-the Software or modifications thereof, without specific, written prior
-permission.
-
-To the extent it has a right to do so, IBM grants an immunity from suit
-under its patents, if any, for the use, sale or manufacture of products to
-the extent that such products are used for performing Domain Name System
-dynamic updates in TCP/IP networks by means of the Software. No immunity is
-granted for any product per se or for any other function of any product.
-
-THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
-DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
-OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
-IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
-
--------------------------------------------------------------------
-
-Portions Copyright(C) 1995, Jason Downs. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS
-OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT,
-INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-The author of this software is David M. Gay.
-
-Copyright (C) 1998 by Lucent Technologies
-All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and
-its documentation for any purpose and without fee is hereby
-granted, provided that the above copyright notice appear in all
-copies and that both that the copyright notice and this
-permission notice and warranty disclaimer appear in supporting
-documentation, and that the name of Lucent or any of its entities
-not be used in advertising or publicity pertaining to
-distribution of the software without specific, written prior
-permission.
-
-LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
-IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
-SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
-IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
-THIS SOFTWARE.
-
--------------------------------------------------------------------
-
-The author of this software is David M. Gay.
-
-Copyright (C) 1998, 1999 by Lucent Technologies
-All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and
-its documentation for any purpose and without fee is hereby
-granted, provided that the above copyright notice appear in all
-copies and that both that the copyright notice and this
-permission notice and warranty disclaimer appear in supporting
-documentation, and that the name of Lucent or any of its entities
-not be used in advertising or publicity pertaining to
-distribution of the software without specific, written prior
-permission.
-
-LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
-IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
-SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
-IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
-THIS SOFTWARE.
-
--------------------------------------------------------------------
-
-The author of this software is David M. Gay.
-
-Copyright (C) 1998, 2000 by Lucent Technologies
-All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and
-its documentation for any purpose and without fee is hereby
-granted, provided that the above copyright notice appear in all
-copies and that both that the copyright notice and this
-permission notice and warranty disclaimer appear in supporting
-documentation, and that the name of Lucent or any of its entities
-not be used in advertising or publicity pertaining to
-distribution of the software without specific, written prior
-permission.
-
-LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
-IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
-SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
-IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
-THIS SOFTWARE.
-
--------------------------------------------------------------------
-
-The author of this software is David M. Gay.
-
-Copyright (C) 1998-2000 by Lucent Technologies
-All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and
-its documentation for any purpose and without fee is hereby
-granted, provided that the above copyright notice appear in all
-copies and that both that the copyright notice and this
-permission notice and warranty disclaimer appear in supporting
-documentation, and that the name of Lucent or any of its entities
-not be used in advertising or publicity pertaining to
-distribution of the software without specific, written prior
-permission.
-
-LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
-IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
-SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
-IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
-THIS SOFTWARE.
-
--------------------------------------------------------------------
-
-The author of this software is David M. Gay.
-
-Copyright (C) 1998-2001 by Lucent Technologies
-All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and
-its documentation for any purpose and without fee is hereby
-granted, provided that the above copyright notice appear in all
-copies and that both that the copyright notice and this
-permission notice and warranty disclaimer appear in supporting
-documentation, and that the name of Lucent or any of its entities
-not be used in advertising or publicity pertaining to
-distribution of the software without specific, written prior
-permission.
-
-LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
-IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
-SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
-IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
-THIS SOFTWARE.
-
--------------------------------------------------------------------
-
-The author of this software is David M. Gay.
-
-Copyright (C) 2000 by Lucent Technologies
-All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and
-its documentation for any purpose and without fee is hereby
-granted, provided that the above copyright notice appear in all
-copies and that both that the copyright notice and this
-permission notice and warranty disclaimer appear in supporting
-documentation, and that the name of Lucent or any of its entities
-not be used in advertising or publicity pertaining to
-distribution of the software without specific, written prior
-permission.
-
-LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
-IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
-SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
-IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
-THIS SOFTWARE.
-
--------------------------------------------------------------------
-
diff --git a/third_party/address_sorting/address_sorting.c b/third_party/address_sorting/address_sorting.c
index ec46099..e4f3b53 100644
--- a/third_party/address_sorting/address_sorting.c
+++ b/third_party/address_sorting/address_sorting.c
@@ -225,15 +225,15 @@
static int compare_source_dest_scope_matches(
const address_sorting_sortable* first,
const address_sorting_sortable* second) {
- int first_src_dst_scope_matches = 0;
+ bool first_src_dst_scope_matches = false;
if (sockaddr_get_scope(&first->dest_addr) ==
sockaddr_get_scope(&first->source_addr)) {
- first_src_dst_scope_matches = 1;
+ first_src_dst_scope_matches = true;
}
- int second_src_dst_scope_matches = 0;
+ bool second_src_dst_scope_matches = false;
if (sockaddr_get_scope(&second->dest_addr) ==
sockaddr_get_scope(&second->source_addr)) {
- second_src_dst_scope_matches = 1;
+ second_src_dst_scope_matches = true;
}
if (first_src_dst_scope_matches != second_src_dst_scope_matches) {
return first_src_dst_scope_matches ? -1 : 1;
@@ -244,18 +244,18 @@
static int compare_source_dest_labels_match(
const address_sorting_sortable* first,
const address_sorting_sortable* second) {
- int first_label_matches = 0;
+ bool first_label_matches = false;
if (get_label_value(&first->dest_addr) ==
get_label_value(&first->source_addr)) {
- first_label_matches = 1;
+ first_label_matches = true;
}
- int second_label_matches = 0;
+ bool second_label_matches = false;
if (get_label_value(&second->dest_addr) ==
get_label_value(&second->source_addr)) {
- second_label_matches = 1;
+ second_label_matches = true;
}
if (first_label_matches != second_label_matches) {
- return first_label_matches ? 1 : 1;
+ return first_label_matches ? -1 : 1;
}
return 0;
}
@@ -366,4 +366,5 @@
abort();
}
g_current_source_addr_factory->vtable->destroy(g_current_source_addr_factory);
+ g_current_source_addr_factory = NULL;
}
diff --git a/third_party/protobuf b/third_party/protobuf
index 2761122..b5fbb74 160000
--- a/third_party/protobuf
+++ b/third_party/protobuf
@@ -1 +1 @@
-Subproject commit 2761122b810fe8861004ae785cc3ab39f384d342
+Subproject commit b5fbb742af122b565925987e65c08957739976a7
diff --git a/tools/codegen/core/gen_stats_data.py b/tools/codegen/core/gen_stats_data.py
index 5c9d9e5..3ebd00d 100755
--- a/tools/codegen/core/gen_stats_data.py
+++ b/tools/codegen/core/gen_stats_data.py
@@ -230,13 +230,11 @@
print >> H, "#ifndef GRPC_CORE_LIB_DEBUG_STATS_DATA_H"
print >> H, "#define GRPC_CORE_LIB_DEBUG_STATS_DATA_H"
print >> H
+ print >> H, "#include <grpc/support/port_platform.h>"
+ print >> H
print >> H, "#include <inttypes.h>"
print >> H, "#include \"src/core/lib/iomgr/exec_ctx.h\""
print >> H
- print >> H, "#ifdef __cplusplus"
- print >> H, "extern \"C\" {"
- print >> H, "#endif"
- print >> H
for typename, instances in sorted(inst_map.items()):
print >> H, "typedef enum {"
@@ -290,10 +288,6 @@
inst_map['Histogram'])
print >> H
- print >> H, "#ifdef __cplusplus"
- print >> H, "}"
- print >> H, "#endif"
- print >> H
print >> H, "#endif /* GRPC_CORE_LIB_DEBUG_STATS_DATA_H */"
with open('src/core/lib/debug/stats_data.cc', 'w') as C:
@@ -316,10 +310,13 @@
[C],
["Automatically generated by tools/codegen/core/gen_stats_data.py"])
- print >> C, "#include \"src/core/lib/debug/stats_data.h\""
+ print >> C, "#include <grpc/support/port_platform.h>"
+ print >> C
print >> C, "#include \"src/core/lib/debug/stats.h\""
+ print >> C, "#include \"src/core/lib/debug/stats_data.h\""
+ print >> C, "#include \"src/core/lib/gpr/useful.h\""
print >> C, "#include \"src/core/lib/iomgr/exec_ctx.h\""
- print >> C, "#include <grpc/support/useful.h>"
+ print >> C
histo_code = []
for histogram in inst_map['Histogram']:
diff --git a/tools/distrib/build_ruby_environment_macos.sh b/tools/distrib/build_ruby_environment_macos.sh
index 4a388a0..9e3e3b4 100644
--- a/tools/distrib/build_ruby_environment_macos.sh
+++ b/tools/distrib/build_ruby_environment_macos.sh
@@ -23,9 +23,9 @@
# See https://github.com/grpc/grpc/issues/12161 for verconf.h patch details
patch "$CROSS_RUBY" << EOF
---- cross-ruby.rake 2017-09-27 16:46:00.311020325 +0200
-+++ patched 2017-09-27 16:49:46.127016895 +0200
-@@ -133,7 +133,8 @@
+--- cross-ruby.rake 2018-04-10 11:32:16.000000000 -0700
++++ patched 2018-04-10 11:40:25.000000000 -0700
+@@ -133,8 +133,10 @@
"--host=#{MINGW_HOST}",
"--target=#{MINGW_TARGET}",
"--build=#{RUBY_BUILD}",
@@ -33,9 +33,11 @@
+ '--enable-static',
+ '--disable-shared',
'--disable-install-doc',
++ '--without-gmp',
'--with-ext='
]
-@@ -151,6 +152,7 @@
+
+@@ -151,6 +153,7 @@
# make
file "#{USER_HOME}/builds/#{MINGW_HOST}/#{RUBY_CC_VERSION}/ruby.exe" => ["#{USER_HOME}/builds/#{MINGW_HOST}/#{RUBY_CC_VERSION}/Makefile"] do |t|
chdir File.dirname(t.prerequisites.first) do
diff --git a/tools/distrib/check_copyright.py b/tools/distrib/check_copyright.py
index e7893a1..09eecf4 100755
--- a/tools/distrib/check_copyright.py
+++ b/tools/distrib/check_copyright.py
@@ -93,11 +93,12 @@
# status.proto copied from googleapis
'src/proto/grpc/status/status.proto',
- # Gradle wrapper used to build for Android
+ # Gradle wrappers used to build for Android
'examples/android/helloworld/gradlew.bat',
+ 'src/android/test/interop/gradlew.bat',
))
-RE_YEAR = r'Copyright (?P<first_year>[0-9]+\-)?(?P<last_year>[0-9]+) gRPC authors.'
+RE_YEAR = r'Copyright (?P<first_year>[0-9]+\-)?(?P<last_year>[0-9]+) ([Tt]he )?gRPC [Aa]uthors(\.|)'
RE_LICENSE = dict(
(k, r'\n'.join(LICENSE_PREFIX[k] +
(RE_YEAR if re.search(RE_YEAR, line) else re.escape(line))
diff --git a/tools/distrib/pylint_code.sh b/tools/distrib/pylint_code.sh
index 7175f1e..013b666 100755
--- a/tools/distrib/pylint_code.sh
+++ b/tools/distrib/pylint_code.sh
@@ -25,15 +25,24 @@
'src/python/grpcio_testing/grpc_testing'
)
-VIRTUALENV=python_pylint_venv
+TEST_DIRS=(
+ 'src/python/grpcio_tests/tests'
+)
-virtualenv $VIRTUALENV
-PYTHON=$(realpath $VIRTUALENV/bin/python)
-$PYTHON -m pip install --upgrade pip==9.0.1
+VIRTUALENV=python_pylint_venv
+python -m virtualenv $VIRTUALENV
+
+PYTHON=$VIRTUALENV/bin/python
+
+$PYTHON -m pip install --upgrade pip==10.0.1
$PYTHON -m pip install pylint==1.6.5
for dir in "${DIRS[@]}"; do
$PYTHON -m pylint --rcfile=.pylintrc -rn "$dir" || exit $?
done
+for dir in "${TEST_DIRS[@]}"; do
+ $PYTHON -m pylint --rcfile=.pylintrc-tests -rn "$dir" || exit $?
+done
+
exit 0
diff --git a/tools/distrib/python/docgen.py b/tools/distrib/python/docgen.py
index 4d6fcb5..732d948 100755
--- a/tools/distrib/python/docgen.py
+++ b/tools/distrib/python/docgen.py
@@ -70,7 +70,7 @@
'env': environment
},
{
- 'args': [VIRTUALENV_PIP_PATH, 'install', '--upgrade', 'pip==9.0.1'],
+ 'args': [VIRTUALENV_PIP_PATH, 'install', '--upgrade', 'pip==10.0.1'],
'env': environment
},
{
diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py
index e8ca685..f0367e2 100644
--- a/tools/distrib/python/grpcio_tools/grpc_version.py
+++ b/tools/distrib/python/grpcio_tools/grpc_version.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!!
-VERSION = '1.11.0.dev0'
+VERSION = '1.13.0.dev0'
diff --git a/tools/distrib/python/grpcio_tools/protoc_lib_deps.py b/tools/distrib/python/grpcio_tools/protoc_lib_deps.py
index 2c65fca..a0e1419 100644
--- a/tools/distrib/python/grpcio_tools/protoc_lib_deps.py
+++ b/tools/distrib/python/grpcio_tools/protoc_lib_deps.py
@@ -20,4 +20,4 @@
CC_INCLUDE='third_party/protobuf/src'
PROTO_INCLUDE='third_party/protobuf/src'
-PROTOBUF_SUBMODULE_VERSION="2761122b810fe8861004ae785cc3ab39f384d342"
+PROTOBUF_SUBMODULE_VERSION="b5fbb742af122b565925987e65c08957739976a7"
diff --git a/tools/distrib/yapf_code.sh b/tools/distrib/yapf_code.sh
index d188a02..27c5e31 100755
--- a/tools/distrib/yapf_code.sh
+++ b/tools/distrib/yapf_code.sh
@@ -30,11 +30,11 @@
VIRTUALENV=yapf_virtual_environment
-virtualenv $VIRTUALENV
-PYTHON=$(realpath "${VIRTUALENV}/bin/python")
-$PYTHON -m pip install --upgrade pip==9.0.1
-$PYTHON -m pip install --upgrade futures
-$PYTHON -m pip install yapf==0.20.0
+python -m virtualenv $VIRTUALENV
+PYTHON=${VIRTUALENV}/bin/python
+"$PYTHON" -m pip install --upgrade pip==10.0.1
+"$PYTHON" -m pip install --upgrade futures
+"$PYTHON" -m pip install yapf==0.20.0
yapf() {
local exclusion exclusion_args=()
diff --git a/tools/dockerfile/distribtest/python_dev_arch_x64/Dockerfile b/tools/dockerfile/distribtest/python_dev_arch_x64/Dockerfile
new file mode 100644
index 0000000..7f09fd6
--- /dev/null
+++ b/tools/dockerfile/distribtest/python_dev_arch_x64/Dockerfile
@@ -0,0 +1,22 @@
+# 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.
+
+FROM base/archlinux
+
+RUN pacman --noconfirm -Syy
+RUN pacman --noconfirm -S openssl
+RUN pacman --noconfirm -S python2
+RUN pacman --noconfirm -S python2-pip
+RUN pip2 install virtualenv
+RUN pacman --noconfirm -S base-devel
diff --git a/tools/dockerfile/distribtest/python_dev_centos7_x64/Dockerfile b/tools/dockerfile/distribtest/python_dev_centos7_x64/Dockerfile
new file mode 100644
index 0000000..954146c
--- /dev/null
+++ b/tools/dockerfile/distribtest/python_dev_centos7_x64/Dockerfile
@@ -0,0 +1,22 @@
+# 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.
+
+FROM centos:7
+
+RUN yum install -y python
+RUN yum install -y epel-release
+RUN yum install -y python-pip
+RUN pip install virtualenv
+RUN yum groupinstall -y 'Development Tools'
+RUN yum install -y python-devel
diff --git a/tools/dockerfile/distribtest/python_dev_fedora22_x64/Dockerfile b/tools/dockerfile/distribtest/python_dev_fedora22_x64/Dockerfile
new file mode 100644
index 0000000..d86ad37
--- /dev/null
+++ b/tools/dockerfile/distribtest/python_dev_fedora22_x64/Dockerfile
@@ -0,0 +1,23 @@
+# 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.
+
+FROM fedora:22
+
+RUN yum clean all && yum update -y && yum install -y python python-pip
+RUN pip install virtualenv
+
+RUN yum groupinstall -y "Development Tools"
+RUN yum install -y redhat-rpm-config
+RUN yum install -y gcc-c++
+RUN yum install -y python2-devel
diff --git a/tools/dockerfile/distribtest/python_dev_fedora23_x64/Dockerfile b/tools/dockerfile/distribtest/python_dev_fedora23_x64/Dockerfile
new file mode 100644
index 0000000..0dbf5e4
--- /dev/null
+++ b/tools/dockerfile/distribtest/python_dev_fedora23_x64/Dockerfile
@@ -0,0 +1,23 @@
+# 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.
+
+FROM fedora:23
+
+RUN yum clean all && yum update -y && yum install -y python python-pip
+RUN pip install virtualenv
+
+RUN yum groupinstall -y "Development Tools"
+RUN yum install -y redhat-rpm-config
+RUN yum install -y gcc-c++
+RUN yum install -y python2-devel
diff --git a/tools/dockerfile/distribtest/python_dev_jessie_x64/Dockerfile b/tools/dockerfile/distribtest/python_dev_jessie_x64/Dockerfile
new file mode 100644
index 0000000..c222898
--- /dev/null
+++ b/tools/dockerfile/distribtest/python_dev_jessie_x64/Dockerfile
@@ -0,0 +1,21 @@
+# 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.
+
+FROM debian:jessie
+
+RUN apt-get update && apt-get install -y python python-pip
+RUN pip install virtualenv
+
+RUN apt-get install -y build-essential
+RUN apt-get install -y python-dev
diff --git a/tools/dockerfile/distribtest/python_dev_jessie_x86/Dockerfile b/tools/dockerfile/distribtest/python_dev_jessie_x86/Dockerfile
new file mode 100644
index 0000000..5e0b8ef
--- /dev/null
+++ b/tools/dockerfile/distribtest/python_dev_jessie_x86/Dockerfile
@@ -0,0 +1,27 @@
+# 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.
+
+FROM 32bit/debian:jessie
+
+RUN apt-get update && apt-get install -y python python-pip
+
+RUN pip install virtualenv
+
+RUN apt-get install -y build-essential
+RUN apt-get install -y python-dev
+
+# docker is running on a 64-bit machine, so we need to
+# override "uname -m" to report i686 instead of x86_64, otherwise
+# python will choose a wrong binary package to install.
+ENTRYPOINT ["linux32"]
diff --git a/tools/dockerfile/distribtest/python_dev_ubuntu1404_x64/Dockerfile b/tools/dockerfile/distribtest/python_dev_ubuntu1404_x64/Dockerfile
new file mode 100644
index 0000000..6c842ae
--- /dev/null
+++ b/tools/dockerfile/distribtest/python_dev_ubuntu1404_x64/Dockerfile
@@ -0,0 +1,22 @@
+# 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.
+
+FROM ubuntu:14.04
+
+RUN apt-get update -y && apt-get install -y python python-pip
+
+RUN apt-get install -y build-essential
+RUN apt-get install -y python-dev
+
+RUN pip install virtualenv
diff --git a/tools/dockerfile/distribtest/python_dev_ubuntu1604_x64/Dockerfile b/tools/dockerfile/distribtest/python_dev_ubuntu1604_x64/Dockerfile
new file mode 100644
index 0000000..1ff1e0a
--- /dev/null
+++ b/tools/dockerfile/distribtest/python_dev_ubuntu1604_x64/Dockerfile
@@ -0,0 +1,22 @@
+# 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.
+
+FROM ubuntu:16.04
+
+RUN apt-get update -y && apt-get install -y python python-pip
+
+RUN apt-get install -y build-essential
+RUN apt-get install -y python-dev
+
+RUN pip install virtualenv
diff --git a/tools/dockerfile/distribtest/ruby_fedora20_x64/Dockerfile b/tools/dockerfile/distribtest/ruby_fedora20_x64/Dockerfile
index 5ea51214f..200c5c2 100644
--- a/tools/dockerfile/distribtest/ruby_fedora20_x64/Dockerfile
+++ b/tools/dockerfile/distribtest/ruby_fedora20_x64/Dockerfile
@@ -14,6 +14,6 @@
FROM fedora:20
-RUN yum clean all && yum update -y && yum install -y ruby
+RUN yum clean all && yum update -y && yum install -y ruby findutils
RUN gem install bundler
diff --git a/tools/dockerfile/distribtest/ruby_fedora21_x64/Dockerfile b/tools/dockerfile/distribtest/ruby_fedora21_x64/Dockerfile
index b903401..e1177fd 100644
--- a/tools/dockerfile/distribtest/ruby_fedora21_x64/Dockerfile
+++ b/tools/dockerfile/distribtest/ruby_fedora21_x64/Dockerfile
@@ -19,6 +19,6 @@
# https://github.com/docker/docker/issues/10180
RUN yum install -y yum-plugin-ovl
-RUN yum clean all && yum update -y && yum install -y ruby
+RUN yum clean all && yum update -y && yum install -y ruby findutils
RUN gem install bundler
diff --git a/tools/dockerfile/distribtest/ruby_fedora22_x64/Dockerfile b/tools/dockerfile/distribtest/ruby_fedora22_x64/Dockerfile
index 0d57370..848c5be 100644
--- a/tools/dockerfile/distribtest/ruby_fedora22_x64/Dockerfile
+++ b/tools/dockerfile/distribtest/ruby_fedora22_x64/Dockerfile
@@ -14,6 +14,6 @@
FROM fedora:22
-RUN yum clean all && yum update -y && yum install -y ruby
+RUN yum clean all && yum update -y && yum install -y ruby findutils
RUN gem install bundler
diff --git a/tools/dockerfile/distribtest/ruby_fedora23_x64/Dockerfile b/tools/dockerfile/distribtest/ruby_fedora23_x64/Dockerfile
index 318993b..47dd577 100644
--- a/tools/dockerfile/distribtest/ruby_fedora23_x64/Dockerfile
+++ b/tools/dockerfile/distribtest/ruby_fedora23_x64/Dockerfile
@@ -14,6 +14,6 @@
FROM fedora:23
-RUN yum clean all && yum update -y && yum install -y ruby
+RUN yum clean all && yum update -y && yum install -y ruby findutils
RUN gem install bundler
diff --git a/tools/dockerfile/grpc_artifact_android_ndk/Dockerfile b/tools/dockerfile/grpc_artifact_android_ndk/Dockerfile
new file mode 100644
index 0000000..77b6acf
--- /dev/null
+++ b/tools/dockerfile/grpc_artifact_android_ndk/Dockerfile
@@ -0,0 +1,68 @@
+# 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.
+
+# Docker file for building gRPC artifacts.
+
+# Recent enough cmake (>=3.9) needed by Android SDK
+FROM debian:sid
+
+RUN apt-get update && apt-get install -y debian-keyring && apt-key update
+
+# Install Git and basic packages.
+RUN apt-get update && apt-key update && apt-get install -y \
+ autoconf \
+ autotools-dev \
+ build-essential \
+ bzip2 \
+ clang \
+ curl \
+ gcc \
+ gcc-multilib \
+ git \
+ golang \
+ libc6 \
+ libc6-dbg \
+ libc6-dev \
+ libgtest-dev \
+ libtool \
+ make \
+ perl \
+ strace \
+ python-dev \
+ python-setuptools \
+ python-yaml \
+ telnet \
+ unzip \
+ wget \
+ zip && apt-get clean
+
+# Cmake for cross-compilation
+RUN apt-get update && apt-get install -y cmake golang && apt-get clean
+
+##################
+# Android NDK
+
+# Download and install Android NDK
+RUN wget -q https://dl.google.com/android/repository/android-ndk-r16b-linux-x86_64.zip -O android_ndk.zip \
+ && unzip -q android_ndk.zip \
+ && rm android_ndk.zip \
+ && mv ./android-ndk-r16b /opt
+ENV ANDROID_NDK_PATH /opt/android-ndk-r16b
+
+RUN apt-get update && apt-get install -y libpthread-stubs0-dev && apt-get clean
+
+RUN mkdir /var/local/jenkins
+
+# Define the default command.
+CMD ["bash"]
diff --git a/tools/dockerfile/grpc_clang_format/clang_format_all_the_things.sh b/tools/dockerfile/grpc_clang_format/clang_format_all_the_things.sh
index 08c6a96..3b901ae 100755
--- a/tools/dockerfile/grpc_clang_format/clang_format_all_the_things.sh
+++ b/tools/dockerfile/grpc_clang_format/clang_format_all_the_things.sh
@@ -16,10 +16,10 @@
set -e
# directories to run against
-DIRS="src/core/lib src/core/tsi src/core/ext src/cpp test/core test/cpp include src/compiler src/csharp src/ruby third_party/address_sorting"
+DIRS="src/core/lib src/core/tsi src/core/ext src/cpp test/core test/cpp include src/compiler src/csharp src/ruby third_party/address_sorting src/objective-c"
# file matching patterns to check
-GLOB="*.h *.c *.cc"
+GLOB="*.h *.c *.cc *.m *.mm"
# clang format command
CLANG_FORMAT=${CLANG_FORMAT:-clang-format-5.0}
@@ -29,7 +29,7 @@
do
for glob in $GLOB
do
- files="$files `find ${CLANG_FORMAT_ROOT}/$dir -name $glob -and -not -name '*.generated.*' -and -not -name '*.pb.h' -and -not -name '*.pb.c' -and -not -name '*.pb.cc' -and -not -name end2end_tests.cc -and -not -name end2end_nosec_tests.cc -and -not -name public_headers_must_be_c89.c`"
+ files="$files `find ${CLANG_FORMAT_ROOT}/$dir -name $glob -and -not -name '*.generated.*' -and -not -name '*.pb.h' -and -not -name '*.pb.c' -and -not -name '*.pb.cc' -and -not -name '*.pbobjc.h' -and -not -name '*.pbobjc.m' -and -not -name '*.pbrpc.h' -and -not -name '*.pbrpc.m' -and -not -name end2end_tests.cc -and -not -name end2end_nosec_tests.cc -and -not -name public_headers_must_be_c89.c`"
done
done
diff --git a/tools/dockerfile/grpc_clang_tidy/Dockerfile b/tools/dockerfile/grpc_clang_tidy/Dockerfile
index eeba455..dec7680 100644
--- a/tools/dockerfile/grpc_clang_tidy/Dockerfile
+++ b/tools/dockerfile/grpc_clang_tidy/Dockerfile
@@ -33,9 +33,9 @@
python-pip
# Install Python packages from PyPI
-RUN pip install --upgrade pip==9.0.1
+RUN pip install --upgrade pip==10.0.1
RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.0.post1 six==1.10.0 twisted==17.5.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 twisted==17.5.0
ADD clang_tidy_all_the_things.sh /
diff --git a/tools/dockerfile/interoptest/grpc_interop_android_java/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_android_java/Dockerfile
deleted file mode 100644
index 519cdbf..0000000
--- a/tools/dockerfile/interoptest/grpc_interop_android_java/Dockerfile
+++ /dev/null
@@ -1,78 +0,0 @@
-# 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.
-
-FROM debian:jessie
-
-# Install JDK 8 and Git
-RUN echo oracle-java8-installer shared/accepted-oracle-license-v1-1 select true | /usr/bin/debconf-set-selections && \
- echo "deb http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main" | tee /etc/apt/sources.list.d/webupd8team-java.list && \
- echo "deb-src http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main" | tee -a /etc/apt/sources.list.d/webupd8team-java.list && \
- apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys EEA14886
-RUN apt-get update && apt-get -y install \
- git \
- libapr1 \
- oracle-java8-installer \
- && \
- apt-get clean && rm -r /var/cache/oracle-jdk8-installer/
-ENV JAVA_HOME /usr/lib/jvm/java-8-oracle
-ENV PATH $PATH:$JAVA_HOME/bin
-
-# Install protobuf
-RUN apt-get update && apt-get install -y \
- autoconf \
- build-essential \
- curl \
- gcc \
- libtool \
- unzip \
- && \
- apt-get clean
-WORKDIR /
-RUN git clone https://github.com/google/protobuf.git
-WORKDIR /protobuf
-RUN git checkout v3.3.1 && \
- ./autogen.sh && \
- ./configure && \
- make && \
- make check && \
- make install
-
-# Install gcloud command line tools
-ENV CLOUD_SDK_REPO "cloud-sdk-jessie"
-RUN echo "deb http://packages.cloud.google.com/apt $CLOUD_SDK_REPO main" | tee -a /etc/apt/sources.list.d/google-cloud-sdk.list && \
- curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - && \
- apt-get update && apt-get install -y google-cloud-sdk && apt-get clean && \
- gcloud config set component_manager/disable_update_check true
-
-# Install Android SDK
-WORKDIR /
-RUN mkdir android-sdk
-WORKDIR android-sdk
-RUN wget -q https://dl.google.com/android/repository/tools_r25.2.5-linux.zip && \
- unzip -qq tools_r25.2.5-linux.zip && \
- rm tools_r25.2.5-linux.zip && \
- echo y | tools/bin/sdkmanager "platforms;android-22" && \
- echo y | tools/bin/sdkmanager "build-tools;25.0.2" && \
- echo y | tools/bin/sdkmanager "extras;android;m2repository" && \
- echo y | tools/bin/sdkmanager "extras;google;google_play_services" && \
- echo y | tools/bin/sdkmanager "extras;google;m2repository" && \
- echo y | tools/bin/sdkmanager "patcher;v4" && \
- echo y | tools/bin/sdkmanager "platform-tools"
-ENV ANDROID_HOME "/android-sdk"
-
-# Reset the working directory
-WORKDIR /
-
-# Define the default command.
-CMD ["bash"]
diff --git a/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile
index af2ab90..e806ba5 100644
--- a/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile
+++ b/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile
@@ -60,9 +60,9 @@
python-pip
# Install Python packages from PyPI
-RUN pip install --upgrade pip==9.0.1
+RUN pip install --upgrade pip==10.0.1
RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.0.post1 six==1.10.0 twisted==17.5.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 twisted==17.5.0
#================
# C# dependencies
diff --git a/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile
index af2ab90..e806ba5 100644
--- a/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile
+++ b/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile
@@ -60,9 +60,9 @@
python-pip
# Install Python packages from PyPI
-RUN pip install --upgrade pip==9.0.1
+RUN pip install --upgrade pip==10.0.1
RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.0.post1 six==1.10.0 twisted==17.5.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 twisted==17.5.0
#================
# C# dependencies
diff --git a/tools/dockerfile/interoptest/grpc_interop_cxx/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_cxx/Dockerfile
index ec5338b..d3eb456 100644
--- a/tools/dockerfile/interoptest/grpc_interop_cxx/Dockerfile
+++ b/tools/dockerfile/interoptest/grpc_interop_cxx/Dockerfile
@@ -60,9 +60,9 @@
python-pip
# Install Python packages from PyPI
-RUN pip install --upgrade pip==9.0.1
+RUN pip install --upgrade pip==10.0.1
RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.0.post1 six==1.10.0 twisted==17.5.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 twisted==17.5.0
#=================
# C++ dependencies
diff --git a/tools/dockerfile/interoptest/grpc_interop_go/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_go/Dockerfile
index a775961..b136259 100644
--- a/tools/dockerfile/interoptest/grpc_interop_go/Dockerfile
+++ b/tools/dockerfile/interoptest/grpc_interop_go/Dockerfile
@@ -28,9 +28,9 @@
python-pip
# Install Python packages from PyPI
-RUN pip install --upgrade pip==9.0.1
+RUN pip install --upgrade pip==10.0.1
RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.0.post1 six==1.10.0 twisted==17.5.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 twisted==17.5.0
# Define the default command.
CMD ["bash"]
diff --git a/tools/dockerfile/interoptest/grpc_interop_go1.7/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_go1.7/Dockerfile
index c296c8c..d43d0e4 100644
--- a/tools/dockerfile/interoptest/grpc_interop_go1.7/Dockerfile
+++ b/tools/dockerfile/interoptest/grpc_interop_go1.7/Dockerfile
@@ -28,9 +28,9 @@
python-pip
# Install Python packages from PyPI
-RUN pip install --upgrade pip==9.0.1
+RUN pip install --upgrade pip==10.0.1
RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.0.post1 six==1.10.0 twisted==17.5.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 twisted==17.5.0
# Define the default command.
CMD ["bash"]
diff --git a/tools/dockerfile/interoptest/grpc_interop_go1.8/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_go1.8/Dockerfile
index 9ac0b97..17ca678 100644
--- a/tools/dockerfile/interoptest/grpc_interop_go1.8/Dockerfile
+++ b/tools/dockerfile/interoptest/grpc_interop_go1.8/Dockerfile
@@ -28,9 +28,9 @@
python-pip
# Install Python packages from PyPI
-RUN pip install --upgrade pip==9.0.1
+RUN pip install --upgrade pip==10.0.1
RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.0.post1 six==1.10.0 twisted==17.5.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 twisted==17.5.0
# Define the default command.
CMD ["bash"]
diff --git a/tools/dockerfile/interoptest/grpc_interop_http2/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_http2/Dockerfile
index 92a2faa..e7555c9 100644
--- a/tools/dockerfile/interoptest/grpc_interop_http2/Dockerfile
+++ b/tools/dockerfile/interoptest/grpc_interop_http2/Dockerfile
@@ -28,9 +28,9 @@
python-pip
# Install Python packages from PyPI
-RUN pip install --upgrade pip==9.0.1
+RUN pip install --upgrade pip==10.0.1
RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.0.post1 six==1.10.0 twisted==17.5.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 twisted==17.5.0
RUN pip install twisted h2==2.6.1 hyper
diff --git a/tools/dockerfile/interoptest/grpc_interop_java/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_java/Dockerfile
index 34b4e39..fc29ada 100644
--- a/tools/dockerfile/interoptest/grpc_interop_java/Dockerfile
+++ b/tools/dockerfile/interoptest/grpc_interop_java/Dockerfile
@@ -43,9 +43,9 @@
python-pip
# Install Python packages from PyPI
-RUN pip install --upgrade pip==9.0.1
+RUN pip install --upgrade pip==10.0.1
RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.0.post1 six==1.10.0 twisted==17.5.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 twisted==17.5.0
# Trigger download of as many Gradle artifacts as possible.
diff --git a/tools/dockerfile/interoptest/grpc_interop_java_oracle8/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_java_oracle8/Dockerfile
index 34b4e39..fc29ada 100644
--- a/tools/dockerfile/interoptest/grpc_interop_java_oracle8/Dockerfile
+++ b/tools/dockerfile/interoptest/grpc_interop_java_oracle8/Dockerfile
@@ -43,9 +43,9 @@
python-pip
# Install Python packages from PyPI
-RUN pip install --upgrade pip==9.0.1
+RUN pip install --upgrade pip==10.0.1
RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.0.post1 six==1.10.0 twisted==17.5.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 twisted==17.5.0
# Trigger download of as many Gradle artifacts as possible.
diff --git a/tools/dockerfile/interoptest/grpc_interop_node/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_node/Dockerfile
index b480d31..539a869 100644
--- a/tools/dockerfile/interoptest/grpc_interop_node/Dockerfile
+++ b/tools/dockerfile/interoptest/grpc_interop_node/Dockerfile
@@ -60,9 +60,9 @@
python-pip
# Install Python packages from PyPI
-RUN pip install --upgrade pip==9.0.1
+RUN pip install --upgrade pip==10.0.1
RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.0.post1 six==1.10.0 twisted==17.5.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 twisted==17.5.0
#==================
# Node dependencies
diff --git a/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile
index 07f419f..94290f3 100644
--- a/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile
+++ b/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile
@@ -60,9 +60,13 @@
python-pip
# Install Python packages from PyPI
-RUN pip install --upgrade pip==9.0.1
+RUN pip install --upgrade pip==10.0.1
RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.0.post1 six==1.10.0 twisted==17.5.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 twisted==17.5.0
+
+# Install pip and virtualenv for Python 3.4
+RUN curl https://bootstrap.pypa.io/get-pip.py | python3.4
+RUN python3.4 -m pip install virtualenv
# Prepare ccache
RUN ln -s /usr/bin/ccache /usr/local/bin/gcc
diff --git a/tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile
index 543e207..75e3314 100644
--- a/tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile
+++ b/tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile
@@ -60,9 +60,9 @@
python-pip
# Install Python packages from PyPI
-RUN pip install --upgrade pip==9.0.1
+RUN pip install --upgrade pip==10.0.1
RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.0.post1 six==1.10.0 twisted==17.5.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 twisted==17.5.0
#==================
# Ruby dependencies
diff --git a/tools/dockerfile/test/csharp_jessie_x64/Dockerfile b/tools/dockerfile/test/csharp_jessie_x64/Dockerfile
index 0fae21d..7a8e26d 100644
--- a/tools/dockerfile/test/csharp_jessie_x64/Dockerfile
+++ b/tools/dockerfile/test/csharp_jessie_x64/Dockerfile
@@ -64,9 +64,9 @@
python-pip
# Install Python packages from PyPI
-RUN pip install --upgrade pip==9.0.1
+RUN pip install --upgrade pip==10.0.1
RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.0.post1 six==1.10.0 twisted==17.5.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 twisted==17.5.0
#================
# C# dependencies
diff --git a/tools/dockerfile/test/cxx_alpine_x64/Dockerfile b/tools/dockerfile/test/cxx_alpine_x64/Dockerfile
index c68a5dd..3449af1 100644
--- a/tools/dockerfile/test/cxx_alpine_x64/Dockerfile
+++ b/tools/dockerfile/test/cxx_alpine_x64/Dockerfile
@@ -32,12 +32,13 @@
strace \
python-dev \
py-pip \
+ py-yaml \
unzip \
wget \
zip
# Install Python packages from PyPI
-RUN pip install --upgrade pip==9.0.1
+RUN pip install --upgrade pip==10.0.1
RUN pip install virtualenv
RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.0.post1 six==1.10.0 twisted==17.5.0
diff --git a/tools/dockerfile/test/cxx_jessie_x64/Dockerfile b/tools/dockerfile/test/cxx_jessie_x64/Dockerfile
index dff4c96..f251753 100644
--- a/tools/dockerfile/test/cxx_jessie_x64/Dockerfile
+++ b/tools/dockerfile/test/cxx_jessie_x64/Dockerfile
@@ -64,9 +64,9 @@
python-pip
# Install Python packages from PyPI
-RUN pip install --upgrade pip==9.0.1
+RUN pip install --upgrade pip==10.0.1
RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.0.post1 six==1.10.0 twisted==17.5.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 twisted==17.5.0
#=================
# C++ dependencies
diff --git a/tools/dockerfile/test/cxx_jessie_x86/Dockerfile b/tools/dockerfile/test/cxx_jessie_x86/Dockerfile
index ea1d645..bb9c751 100644
--- a/tools/dockerfile/test/cxx_jessie_x86/Dockerfile
+++ b/tools/dockerfile/test/cxx_jessie_x86/Dockerfile
@@ -64,9 +64,9 @@
python-pip
# Install Python packages from PyPI
-RUN pip install --upgrade pip==9.0.1
+RUN pip install --upgrade pip==10.0.1
RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.0.post1 six==1.10.0 twisted==17.5.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 twisted==17.5.0
#=================
# C++ dependencies
diff --git a/tools/dockerfile/test/cxx_ubuntu1404_x64/Dockerfile b/tools/dockerfile/test/cxx_ubuntu1404_x64/Dockerfile
index 990dac9..b0d9261 100644
--- a/tools/dockerfile/test/cxx_ubuntu1404_x64/Dockerfile
+++ b/tools/dockerfile/test/cxx_ubuntu1404_x64/Dockerfile
@@ -64,9 +64,9 @@
python-pip
# Install Python packages from PyPI
-RUN pip install --upgrade pip==9.0.1
+RUN pip install --upgrade pip==10.0.1
RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.0.post1 six==1.10.0 twisted==17.5.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 twisted==17.5.0
#=================
# C++ dependencies
diff --git a/tools/dockerfile/test/cxx_ubuntu1604_x64/Dockerfile b/tools/dockerfile/test/cxx_ubuntu1604_x64/Dockerfile
index c8943ca..65ff58e 100644
--- a/tools/dockerfile/test/cxx_ubuntu1604_x64/Dockerfile
+++ b/tools/dockerfile/test/cxx_ubuntu1604_x64/Dockerfile
@@ -64,9 +64,9 @@
python-pip
# Install Python packages from PyPI
-RUN pip install --upgrade pip==9.0.1
+RUN pip install --upgrade pip==10.0.1
RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.0.post1 six==1.10.0 twisted==17.5.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 twisted==17.5.0
#=================
# C++ dependencies
diff --git a/tools/dockerfile/test/cxx_ubuntu1710_x64/Dockerfile b/tools/dockerfile/test/cxx_ubuntu1710_x64/Dockerfile
index 11aca17..e926443 100644
--- a/tools/dockerfile/test/cxx_ubuntu1710_x64/Dockerfile
+++ b/tools/dockerfile/test/cxx_ubuntu1710_x64/Dockerfile
@@ -64,9 +64,9 @@
python-pip
# Install Python packages from PyPI
-RUN pip install --upgrade pip==9.0.1
+RUN pip install --upgrade pip==10.0.1
RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.0.post1 six==1.10.0 twisted==17.5.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 twisted==17.5.0
#=================
# C++ dependencies
diff --git a/tools/dockerfile/test/fuzzer/Dockerfile b/tools/dockerfile/test/fuzzer/Dockerfile
index 52666ea..a242492 100644
--- a/tools/dockerfile/test/fuzzer/Dockerfile
+++ b/tools/dockerfile/test/fuzzer/Dockerfile
@@ -64,9 +64,9 @@
python-pip
# Install Python packages from PyPI
-RUN pip install --upgrade pip==9.0.1
+RUN pip install --upgrade pip==10.0.1
RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.0.post1 six==1.10.0 twisted==17.5.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 twisted==17.5.0
#=================
# C++ dependencies
diff --git a/tools/dockerfile/test/multilang_jessie_x64/Dockerfile b/tools/dockerfile/test/multilang_jessie_x64/Dockerfile
index 5818ff9..e22484f 100644
--- a/tools/dockerfile/test/multilang_jessie_x64/Dockerfile
+++ b/tools/dockerfile/test/multilang_jessie_x64/Dockerfile
@@ -140,9 +140,13 @@
python-pip
# Install Python packages from PyPI
-RUN pip install --upgrade pip==9.0.1
+RUN pip install --upgrade pip==10.0.1
RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.0.post1 six==1.10.0 twisted==17.5.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 twisted==17.5.0
+
+# Install pip and virtualenv for Python 3.4
+RUN curl https://bootstrap.pypa.io/get-pip.py | python3.4
+RUN python3.4 -m pip install virtualenv
# Install coverage for Python test coverage reporting
RUN pip install coverage
diff --git a/tools/dockerfile/test/node_jessie_x64/Dockerfile b/tools/dockerfile/test/node_jessie_x64/Dockerfile
index 05c8319..f32b437 100644
--- a/tools/dockerfile/test/node_jessie_x64/Dockerfile
+++ b/tools/dockerfile/test/node_jessie_x64/Dockerfile
@@ -75,9 +75,9 @@
python-pip
# Install Python packages from PyPI
-RUN pip install --upgrade pip==9.0.1
+RUN pip install --upgrade pip==10.0.1
RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.0.post1 six==1.10.0 twisted==17.5.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 twisted==17.5.0
#==================
# Node dependencies
diff --git a/tools/dockerfile/test/php7_jessie_x64/Dockerfile b/tools/dockerfile/test/php7_jessie_x64/Dockerfile
index 865bf69..e96be27 100644
--- a/tools/dockerfile/test/php7_jessie_x64/Dockerfile
+++ b/tools/dockerfile/test/php7_jessie_x64/Dockerfile
@@ -75,9 +75,9 @@
python-pip
# Install Python packages from PyPI
-RUN pip install --upgrade pip==9.0.1
+RUN pip install --upgrade pip==10.0.1
RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.0.post1 six==1.10.0 twisted==17.5.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 twisted==17.5.0
# Prepare ccache
RUN ln -s /usr/bin/ccache /usr/local/bin/gcc
diff --git a/tools/dockerfile/test/php_jessie_x64/Dockerfile b/tools/dockerfile/test/php_jessie_x64/Dockerfile
index fb653d3..88ee267 100644
--- a/tools/dockerfile/test/php_jessie_x64/Dockerfile
+++ b/tools/dockerfile/test/php_jessie_x64/Dockerfile
@@ -64,9 +64,9 @@
python-pip
# Install Python packages from PyPI
-RUN pip install --upgrade pip==9.0.1
+RUN pip install --upgrade pip==10.0.1
RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.0.post1 six==1.10.0 twisted==17.5.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 twisted==17.5.0
#=================
# PHP dependencies
diff --git a/tools/dockerfile/test/python_alpine_x64/Dockerfile b/tools/dockerfile/test/python_alpine_x64/Dockerfile
index 8ae4550..6e06e2d 100644
--- a/tools/dockerfile/test/python_alpine_x64/Dockerfile
+++ b/tools/dockerfile/test/python_alpine_x64/Dockerfile
@@ -37,7 +37,7 @@
zip
# Install Python packages from PyPI
-RUN pip install --upgrade pip==9.0.1
+RUN pip install --upgrade pip==10.0.1
RUN pip install virtualenv
RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.0.post1 six==1.10.0
diff --git a/tools/dockerfile/test/python_jessie_x64/Dockerfile b/tools/dockerfile/test/python_jessie_x64/Dockerfile
index 914e343..bd9d55e 100644
--- a/tools/dockerfile/test/python_jessie_x64/Dockerfile
+++ b/tools/dockerfile/test/python_jessie_x64/Dockerfile
@@ -64,9 +64,13 @@
python-pip
# Install Python packages from PyPI
-RUN pip install --upgrade pip==9.0.1
+RUN pip install --upgrade pip==10.0.1
RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.0.post1 six==1.10.0 twisted==17.5.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 twisted==17.5.0
+
+# Install pip and virtualenv for Python 3.4
+RUN curl https://bootstrap.pypa.io/get-pip.py | python3.4
+RUN python3.4 -m pip install virtualenv
# Prepare ccache
RUN ln -s /usr/bin/ccache /usr/local/bin/gcc
diff --git a/tools/dockerfile/test/python_pyenv_x64/Dockerfile b/tools/dockerfile/test/python_pyenv_x64/Dockerfile
index 379f26a..6d72a1c 100644
--- a/tools/dockerfile/test/python_pyenv_x64/Dockerfile
+++ b/tools/dockerfile/test/python_pyenv_x64/Dockerfile
@@ -64,9 +64,9 @@
python-pip
# Install Python packages from PyPI
-RUN pip install --upgrade pip==9.0.1
+RUN pip install --upgrade pip==10.0.1
RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.0.post1 six==1.10.0 twisted==17.5.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 twisted==17.5.0
# Install dependencies for pyenv
RUN apt-get update && apt-get install -y \
@@ -91,6 +91,10 @@
RUN pyenv install pypy-5.3.1
RUN pyenv local 3.5-dev 3.6-dev pypy-5.3.1
+# Install pip and virtualenv for Python 3.4
+RUN curl https://bootstrap.pypa.io/get-pip.py | python3.4
+RUN python3.4 -m pip install virtualenv
+
# Prepare ccache
RUN ln -s /usr/bin/ccache /usr/local/bin/gcc
RUN ln -s /usr/bin/ccache /usr/local/bin/g++
diff --git a/tools/dockerfile/test/ruby_jessie_x64/Dockerfile b/tools/dockerfile/test/ruby_jessie_x64/Dockerfile
index 63e42fd..37d909a 100644
--- a/tools/dockerfile/test/ruby_jessie_x64/Dockerfile
+++ b/tools/dockerfile/test/ruby_jessie_x64/Dockerfile
@@ -64,9 +64,9 @@
python-pip
# Install Python packages from PyPI
-RUN pip install --upgrade pip==9.0.1
+RUN pip install --upgrade pip==10.0.1
RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.0.post1 six==1.10.0 twisted==17.5.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 twisted==17.5.0
#==================
# Ruby dependencies
diff --git a/tools/dockerfile/test/sanity/Dockerfile b/tools/dockerfile/test/sanity/Dockerfile
index f65adf5..4885843 100644
--- a/tools/dockerfile/test/sanity/Dockerfile
+++ b/tools/dockerfile/test/sanity/Dockerfile
@@ -64,9 +64,9 @@
python-pip
# Install Python packages from PyPI
-RUN pip install --upgrade pip==9.0.1
+RUN pip install --upgrade pip==10.0.1
RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.0.post1 six==1.10.0 twisted==17.5.0
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 twisted==17.5.0
#=================
# C++ dependencies
diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++
index eb6700d..884eabb 100644
--- a/tools/doxygen/Doxyfile.c++
+++ b/tools/doxygen/Doxyfile.c++
@@ -40,7 +40,7 @@
# could be handy for archiving the generated documentation or if some version
# control system is used.
-PROJECT_NUMBER = 1.11.0-dev
+PROJECT_NUMBER = 1.13.0-dev
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
@@ -954,6 +954,8 @@
include/grpcpp/impl/codegen/grpc_library.h \
include/grpcpp/impl/codegen/metadata_map.h \
include/grpcpp/impl/codegen/method_handler_impl.h \
+include/grpcpp/impl/codegen/proto_buffer_reader.h \
+include/grpcpp/impl/codegen/proto_buffer_writer.h \
include/grpcpp/impl/codegen/proto_utils.h \
include/grpcpp/impl/codegen/rpc_method.h \
include/grpcpp/impl/codegen/rpc_service_method.h \
@@ -992,6 +994,8 @@
include/grpcpp/support/byte_buffer.h \
include/grpcpp/support/channel_arguments.h \
include/grpcpp/support/config.h \
+include/grpcpp/support/proto_buffer_reader.h \
+include/grpcpp/support/proto_buffer_writer.h \
include/grpcpp/support/slice.h \
include/grpcpp/support/status.h \
include/grpcpp/support/status_code_enum.h \
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index 52a16d6..66796ba 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -40,7 +40,7 @@
# could be handy for archiving the generated documentation or if some version
# control system is used.
-PROJECT_NUMBER = 1.11.0-dev
+PROJECT_NUMBER = 1.13.0-dev
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
@@ -956,6 +956,8 @@
include/grpcpp/impl/codegen/grpc_library.h \
include/grpcpp/impl/codegen/metadata_map.h \
include/grpcpp/impl/codegen/method_handler_impl.h \
+include/grpcpp/impl/codegen/proto_buffer_reader.h \
+include/grpcpp/impl/codegen/proto_buffer_writer.h \
include/grpcpp/impl/codegen/proto_utils.h \
include/grpcpp/impl/codegen/rpc_method.h \
include/grpcpp/impl/codegen/rpc_service_method.h \
@@ -994,6 +996,8 @@
include/grpcpp/support/byte_buffer.h \
include/grpcpp/support/channel_arguments.h \
include/grpcpp/support/config.h \
+include/grpcpp/support/proto_buffer_reader.h \
+include/grpcpp/support/proto_buffer_writer.h \
include/grpcpp/support/slice.h \
include/grpcpp/support/status.h \
include/grpcpp/support/status_code_enum.h \
@@ -1209,7 +1213,6 @@
src/cpp/thread_manager/thread_manager.cc \
src/cpp/thread_manager/thread_manager.h \
src/cpp/util/byte_buffer_cc.cc \
-src/cpp/util/slice_cc.cc \
src/cpp/util/status.cc \
src/cpp/util/string_ref.cc \
src/cpp/util/time_cc.cc \
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index 85675e9..0969b9c 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -885,6 +885,7 @@
src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc \
src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h \
src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc \
+src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h \
src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h \
src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc \
src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc \
@@ -895,7 +896,6 @@
src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h \
src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc \
src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc \
-src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc \
src/core/ext/filters/client_channel/lb_policy/subchannel_list.h \
src/core/ext/filters/client_channel/lb_policy_factory.cc \
src/core/ext/filters/client_channel/lb_policy_factory.h \
@@ -939,6 +939,8 @@
src/core/ext/filters/deadline/deadline_filter.h \
src/core/ext/filters/http/client/http_client_filter.cc \
src/core/ext/filters/http/client/http_client_filter.h \
+src/core/ext/filters/http/client_authority_filter.cc \
+src/core/ext/filters/http/client_authority_filter.h \
src/core/ext/filters/http/http_filters_plugin.cc \
src/core/ext/filters/http/message_compress/message_compress_filter.cc \
src/core/ext/filters/http/message_compress/message_compress_filter.h \
@@ -960,6 +962,8 @@
src/core/ext/transport/chttp2/README.md \
src/core/ext/transport/chttp2/alpn/alpn.cc \
src/core/ext/transport/chttp2/alpn/alpn.h \
+src/core/ext/transport/chttp2/client/authority.cc \
+src/core/ext/transport/chttp2/client/authority.h \
src/core/ext/transport/chttp2/client/chttp2_connector.cc \
src/core/ext/transport/chttp2/client/chttp2_connector.h \
src/core/ext/transport/chttp2/client/insecure/README.md \
@@ -1492,8 +1496,6 @@
src/core/tsi/ssl_types.h \
src/core/tsi/transport_security.cc \
src/core/tsi/transport_security.h \
-src/core/tsi/transport_security_adapter.cc \
-src/core/tsi/transport_security_adapter.h \
src/core/tsi/transport_security_grpc.cc \
src/core/tsi/transport_security_grpc.h \
src/core/tsi/transport_security_interface.h \
diff --git a/tools/fuzzer/runners/alts_credentials_fuzzer.sh b/tools/fuzzer/runners/alts_credentials_fuzzer.sh
new file mode 100644
index 0000000..3aaff6b
--- /dev/null
+++ b/tools/fuzzer/runners/alts_credentials_fuzzer.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+# 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.
+#
+
+flags="-max_total_time=$runtime -artifact_prefix=fuzzer_output/ -max_len=2048 -timeout=120"
+
+
+if [ "$jobs" != "1" ]
+then
+ flags="-jobs=$jobs -workers=$jobs $flags"
+fi
+
+if [ "$config" == "asan-trace-cmp" ]
+then
+ flags="-use_traces=1 $flags"
+fi
+
+bins/$config/alts_credentials_fuzzer $flags fuzzer_output test/core/security/corpus/alts_credentials_corpus
diff --git a/tools/gce/create_windows_debug_worker.sh b/tools/gce/create_windows_debug_worker.sh
index 6f903b5..3625df8 100755
--- a/tools/gce/create_windows_debug_worker.sh
+++ b/tools/gce/create_windows_debug_worker.sh
@@ -44,12 +44,13 @@
echo 'Created scratch disk, waiting for it to become available.'
sleep 15
+# The image version might need updating.
gcloud compute instances create "$INSTANCE_NAME" \
--project="$CLOUD_PROJECT" \
--zone "$ZONE" \
--machine-type "$MACHINE_TYPE" \
--image-project google.com:kokoro \
- --image kokoro-win7build-v9-prod-debug \
+ --image kokoro-win7build-v11-prod-debug \
--boot-disk-size 500 \
--boot-disk-type pd-ssd \
--tags=allow-ssh \
diff --git a/tools/gce/linux_kokoro_performance_worker_init.sh b/tools/gce/linux_kokoro_performance_worker_init.sh
index 1f98d24..4a1e3e6 100755
--- a/tools/gce/linux_kokoro_performance_worker_init.sh
+++ b/tools/gce/linux_kokoro_performance_worker_init.sh
@@ -72,7 +72,7 @@
sudo apt-get install -y libgflags-dev libgtest-dev libc++-dev clang
# Python dependencies
-sudo pip install --upgrade pip==9.0.1
+sudo pip install --upgrade pip==10.0.1
sudo pip install tabulate
sudo pip install google-api-python-client
sudo pip install virtualenv
diff --git a/tools/gce/linux_performance_worker_init.sh b/tools/gce/linux_performance_worker_init.sh
index 6f68660..7222cef 100755
--- a/tools/gce/linux_performance_worker_init.sh
+++ b/tools/gce/linux_performance_worker_init.sh
@@ -72,7 +72,7 @@
sudo apt-get install -y libgflags-dev libgtest-dev libc++-dev clang
# Python dependencies
-sudo pip install --upgrade pip==9.0.1
+sudo pip install --upgrade pip==10.0.1
sudo pip install tabulate
sudo pip install google-api-python-client
sudo pip install virtualenv
diff --git a/tools/internal_ci/helper_scripts/gen_report_index.sh b/tools/internal_ci/helper_scripts/gen_report_index.sh
deleted file mode 100755
index 576ff67..0000000
--- a/tools/internal_ci/helper_scripts/gen_report_index.sh
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/usr/bin/env bash
-# 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.
-#
-# Generates index.html that will contain links to various test results on kokoro.
-set -e
-
-# change to grpc repo root
-cd $(dirname $0)/../../..
-
-# Kororo URLs are in the form "grpc/job/macos/job/master/job/grpc_build_artifacts"
-KOKORO_JOB_PATH=$(echo "${KOKORO_JOB_NAME}" | sed "s|/|/job/|g")
-
-mkdir -p reports
-
-echo '<html><head></head><body>' > reports/kokoro_index.html
-echo '<h1>'${KOKORO_JOB_NAME}', build '#${KOKORO_BUILD_NUMBER}'</h1>' >> reports/kokoro_index.html
-echo '<h2><a href="https://kokoro2.corp.google.com/job/'${KOKORO_JOB_PATH}'/'${KOKORO_BUILD_NUMBER}'/">Kokoro build dashboard (internal only)</a></h2>' >> reports/kokoro_index.html
-echo '<h2><a href="https://sponge.corp.google.com/invocation?id='${KOKORO_BUILD_ID}'&searchFor=">Test result dashboard (internal only)</a></h2>' >> reports/kokoro_index.html
-echo '<h2><a href="test_report.html">HTML test report (Not available yet)</a></h2>' >> reports/kokoro_index.html
-echo '<h2><a href="test_log.txt">Test log (Not available yet)</a></h2>' >> reports/kokoro_index.html
-echo '</body></html>' >> reports/kokoro_index.html
-
-echo 'Created reports/kokoro_index.html report index'
diff --git a/tools/internal_ci/helper_scripts/prepare_build_linux_rc b/tools/internal_ci/helper_scripts/prepare_build_linux_rc
index 74bbc85..992c540 100644
--- a/tools/internal_ci/helper_scripts/prepare_build_linux_rc
+++ b/tools/internal_ci/helper_scripts/prepare_build_linux_rc
@@ -15,8 +15,6 @@
# Source this rc script to prepare the environment for linux builds
-tools/internal_ci/helper_scripts/gen_report_index.sh
-
# Need to increase open files limit for c tests
ulimit -n 32768
diff --git a/tools/internal_ci/helper_scripts/prepare_build_macos_interop_rc b/tools/internal_ci/helper_scripts/prepare_build_macos_interop_rc
index 786cd45..b0feeef 100644
--- a/tools/internal_ci/helper_scripts/prepare_build_macos_interop_rc
+++ b/tools/internal_ci/helper_scripts/prepare_build_macos_interop_rc
@@ -33,9 +33,3 @@
git clone --recursive https://github.com/grpc/grpc-java ./../grpc-java
git clone --recursive https://github.com/grpc/grpc-node ./../grpc-node
git clone --recursive https://github.com/grpc/grpc-dart ./../grpc-dart
-
-# Set up Docker for Mac
-docker-machine create -d virtualbox --virtualbox-share-folder "/Users/kbuilder/workspace:" default
-docker-machine env default
-eval $(docker-machine env default)
-
diff --git a/tools/internal_ci/helper_scripts/prepare_build_macos_rc b/tools/internal_ci/helper_scripts/prepare_build_macos_rc
index 3a09701..d2b7769 100644
--- a/tools/internal_ci/helper_scripts/prepare_build_macos_rc
+++ b/tools/internal_ci/helper_scripts/prepare_build_macos_rc
@@ -15,8 +15,6 @@
# Source this rc script to prepare the environment for macos builds
-tools/internal_ci/helper_scripts/gen_report_index.sh
-
sudo launchctl limit maxfiles unlimited unlimited
# show current maxfiles
@@ -69,7 +67,12 @@
export PYTHONPATH=/Library/Python/3.4/site-packages
# set xcode version for Obj-C tests
-sudo xcode-select -switch /Applications/Xcode_8.2.1.app/Contents/Developer
+sudo xcode-select -switch /Applications/Xcode_9.2.app/Contents/Developer/
+
+# Disable some unwanted dotnet options
+export NUGET_XMLDOC_MODE=skip
+export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=true
+export DOTNET_CLI_TELEMETRY_OPTOUT=true
# TODO(jtattermusch): better debugging of clock skew, remove once not needed
date
diff --git a/tools/internal_ci/helper_scripts/prepare_build_windows.bat b/tools/internal_ci/helper_scripts/prepare_build_windows.bat
index f625755..f987f8a 100644
--- a/tools/internal_ci/helper_scripts/prepare_build_windows.bat
+++ b/tools/internal_ci/helper_scripts/prepare_build_windows.bat
@@ -16,8 +16,6 @@
@rem set path to python 2.7
set PATH=C:\tools\msys64\usr\bin;C:\Python27;%PATH%
-bash tools/internal_ci/helper_scripts/gen_report_index.sh
-
@rem If this is a PR using RUN_TESTS_FLAGS var, then add flags to filter tests
if defined KOKORO_GITHUB_PULL_REQUEST_NUMBER if defined RUN_TESTS_FLAGS (
chocolatey install -y jq
@@ -36,4 +34,9 @@
@rem Needed for big_query_utils
python -m pip install google-api-python-client
+@rem Disable some unwanted dotnet options
+set NUGET_XMLDOC_MODE=skip
+set DOTNET_SKIP_FIRST_TIME_EXPERIENCE=true
+set DOTNET_CLI_TELEMETRY_OPTOUT=true
+
git submodule update --init
diff --git a/tools/internal_ci/linux/grpc_android.sh b/tools/internal_ci/linux/grpc_android.sh
index c693b77..2220145 100755
--- a/tools/internal_ci/linux/grpc_android.sh
+++ b/tools/internal_ci/linux/grpc_android.sh
@@ -31,7 +31,32 @@
git fetch
git cherry-pick 7daa320065f3bea2b54bf983337d1724f153422d -m 1
-cd ../../examples/android/helloworld
+
+# Build and run interop instrumentation tests on Firebase Test Lab
+
+cd "${REPO_ROOT}/src/android/test/interop/"
+./gradlew assembleDebug \
+ "-Pprotoc=${REPO_ROOT}/third_party/protobuf/src/protoc" \
+ "-Pgrpc_cpp_plugin=${REPO_ROOT}/bins/opt/grpc_cpp_plugin"
+./gradlew assembleDebugAndroidTest \
+ "-Pprotoc=${REPO_ROOT}/third_party/protobuf/src/protoc" \
+ "-Pgrpc_cpp_plugin=${REPO_ROOT}/bins/opt/grpc_cpp_plugin"
+gcloud firebase test android run \
+ --type instrumentation \
+ --app app/build/outputs/apk/debug/app-debug.apk \
+ --test app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk \
+ --device model=Nexus6P,version=27,locale=en,orientation=portrait \
+ --device model=Nexus6P,version=26,locale=en,orientation=portrait \
+ --device model=Nexus6P,version=25,locale=en,orientation=portrait \
+ --device model=Nexus6P,version=24,locale=en,orientation=portrait \
+ --device model=Nexus6P,version=23,locale=en,orientation=portrait \
+ --device model=Nexus6,version=22,locale=en,orientation=portrait \
+ --device model=Nexus6,version=21,locale=en,orientation=portrait
+
+
+# Build hello world example
+
+cd "${REPO_ROOT}/examples/android/helloworld"
./gradlew build \
"-Pprotoc=${REPO_ROOT}/third_party/protobuf/src/protoc" \
"-Pgrpc_cpp_plugin=${REPO_ROOT}/bins/opt/grpc_cpp_plugin"
diff --git a/tools/internal_ci/linux/grpc_asan_on_foundry.sh b/tools/internal_ci/linux/grpc_asan_on_foundry.sh
index 2aebb65..791c56c 100644
--- a/tools/internal_ci/linux/grpc_asan_on_foundry.sh
+++ b/tools/internal_ci/linux/grpc_asan_on_foundry.sh
@@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+export UPLOAD_TEST_RESULTS=true
EXTRA_FLAGS="--copt=-gmlt --strip=never --copt=-fsanitize=address --linkopt=-fsanitize=address --test_timeout=3600"
github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh "${EXTRA_FLAGS}"
diff --git a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh
index 7ec15bf..7881e3a 100755
--- a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh
+++ b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh
@@ -22,8 +22,8 @@
cp ${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db331.json ${KOKORO_KEYSTORE_DIR}/4321_grpc-testing-service
temp_dir=$(mktemp -d)
-ln -f "${KOKORO_GFILE_DIR}/bazel-canary" ${temp_dir}/bazel
-chmod 755 "${KOKORO_GFILE_DIR}/bazel-canary"
+ln -f "${KOKORO_GFILE_DIR}/bazel-release-0.12.0" ${temp_dir}/bazel
+chmod 755 "${KOKORO_GFILE_DIR}/bazel-release-0.12.0"
export PATH="${temp_dir}:${PATH}"
# This should show ${temp_dir}/bazel
which bazel
@@ -37,7 +37,7 @@
# TODO(adelez): implement size for test targets and change test_timeout back
"${KOKORO_GFILE_DIR}/bazel_wrapper.py" \
--host_jvm_args=-Dbazel.DigestFunction=SHA256 \
- test --jobs="100" \
+ test --jobs="200" \
--test_output=errors \
--verbose_failures=true \
--keep_going \
@@ -49,8 +49,20 @@
--strategy=Closure=remote \
--genrule_strategy=remote \
--experimental_strict_action_env=true \
- --experimental_remote_platform_override='properties:{name:"container-image" value:"docker://gcr.io/cloud-marketplace/google/rbe-debian8@sha256:b2d946c1ddc20af250fe85cf98bd648ac5519131659f7c36e64184b433175a33" }' \
+ --experimental_remote_platform_override='properties:{name:"container-image" value:"docker://gcr.io/cloud-marketplace/google/rbe-debian8@sha256:1ede2a929b44d629ec5abe86eee6d7ffea1d5a4d247489a8867d46cfde3e38bd" }' \
--crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/debian8_clang/0.3.0/bazel_0.10.0:toolchain \
--define GRPC_PORT_ISOLATED_RUNTIME=1 \
$1 \
- -- //test/...
+ -- //test/... || FAILED="true"
+
+if [ "$UPLOAD_TEST_RESULTS" != "" ]
+then
+ # Sleep to let ResultStore finish writing results before querying
+ sleep 60
+ python ./tools/run_tests/python_utils/upload_rbe_results.py
+fi
+
+if [ "$FAILED" != "" ]
+then
+ exit 1
+fi
diff --git a/tools/internal_ci/linux/grpc_bazel_on_foundry_dbg.sh b/tools/internal_ci/linux/grpc_bazel_on_foundry_dbg.sh
index f5111e2..192d9d1 100644
--- a/tools/internal_ci/linux/grpc_bazel_on_foundry_dbg.sh
+++ b/tools/internal_ci/linux/grpc_bazel_on_foundry_dbg.sh
@@ -13,6 +13,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-EXTRA_FLAGS="-c dbg --test_timeout=300,450,1200,7200"
+export UPLOAD_TEST_RESULTS=true
+EXTRA_FLAGS="-c dbg --test_timeout=300,450,1200,3600 --runs_per_test_detects_flakes --runs_per_test=2"
github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh "${EXTRA_FLAGS}"
-
diff --git a/tools/internal_ci/linux/grpc_bazel_on_foundry_opt.sh b/tools/internal_ci/linux/grpc_bazel_on_foundry_opt.sh
index 7f3e4cf..6fb3c77 100644
--- a/tools/internal_ci/linux/grpc_bazel_on_foundry_opt.sh
+++ b/tools/internal_ci/linux/grpc_bazel_on_foundry_opt.sh
@@ -13,5 +13,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-EXTRA_FLAGS="-c opt --test_timeout=300,450,1200,7200"
+export UPLOAD_TEST_RESULTS=true
+EXTRA_FLAGS="-c opt --test_timeout=300,450,1200,3600 --runs_per_test_detects_flakes --runs_per_test=2"
github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh "${EXTRA_FLAGS}"
diff --git a/tools/internal_ci/linux/grpc_build_packages.sh b/tools/internal_ci/linux/grpc_build_packages.sh
index 9f65d8e..ff71298 100644
--- a/tools/internal_ci/linux/grpc_build_packages.sh
+++ b/tools/internal_ci/linux/grpc_build_packages.sh
@@ -30,6 +30,7 @@
# where they can be accessed from within a docker container that builds
# the packages
mv ${KOKORO_GFILE_DIR}/github/grpc/artifacts input_artifacts || true
+chmod +x input_artifacts/protoc*/* || true
ls -R input_artifacts || true
tools/run_tests/task_runner.py -f package linux -j 6
diff --git a/tools/internal_ci/linux/grpc_coverage.cfg b/tools/internal_ci/linux/grpc_coverage.cfg
index 56b7745..794a51d 100644
--- a/tools/internal_ci/linux/grpc_coverage.cfg
+++ b/tools/internal_ci/linux/grpc_coverage.cfg
@@ -19,6 +19,7 @@
timeout_mins: 420
action {
define_artifacts {
+ regex: "**/*sponge_log.xml"
regex: "github/grpc/reports/**"
}
}
diff --git a/tools/internal_ci/linux/grpc_coverage.sh b/tools/internal_ci/linux/grpc_coverage.sh
index 12181f0..fd927a8 100755
--- a/tools/internal_ci/linux/grpc_coverage.sh
+++ b/tools/internal_ci/linux/grpc_coverage.sh
@@ -21,10 +21,9 @@
source tools/internal_ci/helper_scripts/prepare_build_linux_rc
python tools/run_tests/run_tests.py \
- --use_docker \
+ --use_docker \
-t \
-l all \
-c gcov \
- -x report.xml \
+ -x sponge_log.xml \
-j 16
-
diff --git a/tools/internal_ci/linux/grpc_sanity_webhook_test.cfg b/tools/internal_ci/linux/grpc_interop_alts.cfg
similarity index 74%
copy from tools/internal_ci/linux/grpc_sanity_webhook_test.cfg
copy to tools/internal_ci/linux/grpc_interop_alts.cfg
index 24e7984..bda76fa 100644
--- a/tools/internal_ci/linux/grpc_sanity_webhook_test.cfg
+++ b/tools/internal_ci/linux/grpc_interop_alts.cfg
@@ -1,4 +1,4 @@
-# Copyright 2017 gRPC authors.
+# Copyright 2018 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -15,16 +15,16 @@
# Config file for the internal CI (in protobuf text format)
# Location of the continuous shell script in repository.
-build_file: "grpc/tools/internal_ci/linux/grpc_run_tests_matrix.sh"
-timeout_mins: 20
+build_file: "grpc/tools/internal_ci/linux/grpc_run_interop_tests.sh"
+timeout_mins: 60
action {
define_artifacts {
- regex: "**/*sponge_log.xml"
+ regex: "**/sponge_log.xml"
regex: "github/grpc/reports/**"
}
}
env_vars {
key: "RUN_TESTS_FLAGS"
- value: "-f basictests linux sanity opt --inner_jobs 16 -j 1 --internal_ci"
+ value: "-l all -s all --use_docker --transport_security alts --internal_ci -t -j 12 --bq_result_table interop_results"
}
diff --git a/tools/internal_ci/linux/grpc_interop_toprod.cfg b/tools/internal_ci/linux/grpc_interop_toprod.cfg
index ff7a98f..8d025c4 100644
--- a/tools/internal_ci/linux/grpc_interop_toprod.cfg
+++ b/tools/internal_ci/linux/grpc_interop_toprod.cfg
@@ -26,5 +26,5 @@
env_vars {
key: "RUN_TESTS_FLAGS"
- value: "-l all --cloud_to_prod --cloud_to_prod_auth --prod_servers default gateway_v4 cloud_gateway cloud_gateway_v4 --use_docker --internal_ci -t -j 12 --bq_result_table interop_results"
+ value: "-l all --cloud_to_prod --cloud_to_prod_auth --prod_servers default gateway_v4 --use_docker --internal_ci -t -j 12 --bq_result_table interop_results"
}
diff --git a/tools/internal_ci/linux/grpc_msan_on_foundry.sh b/tools/internal_ci/linux/grpc_msan_on_foundry.sh
index 60b30ff..5e64479 100644
--- a/tools/internal_ci/linux/grpc_msan_on_foundry.sh
+++ b/tools/internal_ci/linux/grpc_msan_on_foundry.sh
@@ -23,8 +23,8 @@
cp ${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db331.json ${KOKORO_KEYSTORE_DIR}/4321_grpc-testing-service
temp_dir=$(mktemp -d)
-ln -f "${KOKORO_GFILE_DIR}/bazel-canary" ${temp_dir}/bazel
-chmod 755 "${KOKORO_GFILE_DIR}/bazel-canary"
+ln -f "${KOKORO_GFILE_DIR}/bazel-release-0.12.0" ${temp_dir}/bazel
+chmod 755 "${KOKORO_GFILE_DIR}/bazel-release-0.12.0"
export PATH="${temp_dir}:${PATH}"
# This should show ${temp_dir}/bazel
which bazel
@@ -37,7 +37,7 @@
"${KOKORO_GFILE_DIR}/bazel_wrapper.py" \
--host_jvm_args=-Dbazel.DigestFunction=SHA256 \
- test --jobs="100" \
+ test --jobs="200" \
--test_timeout="3600,3600,3600,3600" \
--test_output=errors \
--verbose_failures=true \
@@ -61,4 +61,13 @@
--action_env=LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH \
--host_crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/debian8_clang/0.3.0/bazel_0.10.0:toolchain \
--crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/experimental/debian8_clang/0.3.0/bazel_0.10.0/msan:msan_experimental_toolchain \
- -- //test/...
+ -- //test/... || FAILED="true"
+
+# Sleep to let ResultStore finish writing results before querying
+sleep 60
+python ./tools/run_tests/python_utils/upload_rbe_results.py
+
+if [ "$FAILED" != "" ]
+then
+ exit 1
+fi
diff --git a/tools/internal_ci/linux/grpc_sanity.cfg b/tools/internal_ci/linux/grpc_sanity.cfg
index e06a2f4..9f65918 100644
--- a/tools/internal_ci/linux/grpc_sanity.cfg
+++ b/tools/internal_ci/linux/grpc_sanity.cfg
@@ -26,5 +26,5 @@
env_vars {
key: "RUN_TESTS_FLAGS"
- value: "-f basictests linux sanity opt --inner_jobs 16 -j 1 --internal_ci"
+ value: "-f basictests linux sanity --inner_jobs 16 -j 1 --internal_ci --bq_result_table aggregate_results"
}
diff --git a/tools/internal_ci/linux/grpc_tsan_on_foundry.sh b/tools/internal_ci/linux/grpc_tsan_on_foundry.sh
index aacb1ad..fafa1ce 100644
--- a/tools/internal_ci/linux/grpc_tsan_on_foundry.sh
+++ b/tools/internal_ci/linux/grpc_tsan_on_foundry.sh
@@ -13,6 +13,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+export UPLOAD_TEST_RESULTS=true
EXTRA_FLAGS="--copt=-gmlt --strip=never --copt=-fsanitize=thread --linkopt=-fsanitize=thread --test_timeout=3600"
github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh "${EXTRA_FLAGS}"
-
diff --git a/tools/internal_ci/linux/grpc_ubsan_on_foundry.sh b/tools/internal_ci/linux/grpc_ubsan_on_foundry.sh
index a87547d..0f71ff2 100644
--- a/tools/internal_ci/linux/grpc_ubsan_on_foundry.sh
+++ b/tools/internal_ci/linux/grpc_ubsan_on_foundry.sh
@@ -23,8 +23,8 @@
cp ${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db331.json ${KOKORO_KEYSTORE_DIR}/4321_grpc-testing-service
temp_dir=$(mktemp -d)
-ln -f "${KOKORO_GFILE_DIR}/bazel-canary" ${temp_dir}/bazel
-chmod 755 "${KOKORO_GFILE_DIR}/bazel-canary"
+ln -f "${KOKORO_GFILE_DIR}/bazel-release-0.12.0" ${temp_dir}/bazel
+chmod 755 "${KOKORO_GFILE_DIR}/bazel-release-0.12.0"
export PATH="${temp_dir}:${PATH}"
# This should show ${temp_dir}/bazel
which bazel
@@ -37,7 +37,7 @@
"${KOKORO_GFILE_DIR}/bazel_wrapper.py" \
--host_jvm_args=-Dbazel.DigestFunction=SHA256 \
- test --jobs="100" \
+ test --jobs="200" \
--test_timeout="3600,3600,3600,3600" \
--test_output=errors \
--verbose_failures=true \
@@ -57,4 +57,13 @@
--copt=-fsanitize=undefined \
--linkopt=-fsanitize=undefined \
--crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/experimental/debian8_clang/0.3.0/bazel_0.10.0/ubsan:ubsan_experimental_toolchain \
- -- //test/...
+ -- //test/... || FAILED="true"
+
+# Sleep to let ResultStore finish writing results before querying
+sleep 60
+python ./tools/run_tests/python_utils/upload_rbe_results.py
+
+if [ "$FAILED" != "" ]
+then
+ exit 1
+fi
diff --git a/tools/internal_ci/linux/pull_request/grpc_bazel_on_foundry_dbg.sh b/tools/internal_ci/linux/pull_request/grpc_bazel_on_foundry_dbg.sh
new file mode 100644
index 0000000..8e2aaeb
--- /dev/null
+++ b/tools/internal_ci/linux/pull_request/grpc_bazel_on_foundry_dbg.sh
@@ -0,0 +1,17 @@
+#!/usr/bin/env bash
+# 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.
+
+EXTRA_FLAGS="-c dbg --test_timeout=300,450,1200,3600"
+github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh "${EXTRA_FLAGS}"
diff --git a/tools/internal_ci/linux/pull_request/grpc_bazel_on_foundry_opt.sh b/tools/internal_ci/linux/pull_request/grpc_bazel_on_foundry_opt.sh
new file mode 100644
index 0000000..ded0d36
--- /dev/null
+++ b/tools/internal_ci/linux/pull_request/grpc_bazel_on_foundry_opt.sh
@@ -0,0 +1,17 @@
+#!/usr/bin/env bash
+# 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.
+
+EXTRA_FLAGS="-c opt --test_timeout=300,450,1200,3600"
+github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh "${EXTRA_FLAGS}"
diff --git a/tools/internal_ci/linux/grpc_sanity_webhook_test.cfg b/tools/internal_ci/linux/pull_request/grpc_interop_alts.cfg
similarity index 76%
copy from tools/internal_ci/linux/grpc_sanity_webhook_test.cfg
copy to tools/internal_ci/linux/pull_request/grpc_interop_alts.cfg
index 24e7984..c1253b3 100644
--- a/tools/internal_ci/linux/grpc_sanity_webhook_test.cfg
+++ b/tools/internal_ci/linux/pull_request/grpc_interop_alts.cfg
@@ -1,4 +1,4 @@
-# Copyright 2017 gRPC authors.
+# Copyright 2018 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -15,16 +15,16 @@
# Config file for the internal CI (in protobuf text format)
# Location of the continuous shell script in repository.
-build_file: "grpc/tools/internal_ci/linux/grpc_run_tests_matrix.sh"
-timeout_mins: 20
+build_file: "grpc/tools/internal_ci/linux/grpc_run_interop_tests.sh"
+timeout_mins: 60
action {
define_artifacts {
- regex: "**/*sponge_log.xml"
+ regex: "**/sponge_log.xml"
regex: "github/grpc/reports/**"
}
}
env_vars {
key: "RUN_TESTS_FLAGS"
- value: "-f basictests linux sanity opt --inner_jobs 16 -j 1 --internal_ci"
+ value: "-l all -s all --use_docker --transport_security alts --internal_ci -t -j 12"
}
diff --git a/tools/internal_ci/linux/pull_request/grpc_interop_toprod.cfg b/tools/internal_ci/linux/pull_request/grpc_interop_toprod.cfg
index e141d9f..d14c79a 100644
--- a/tools/internal_ci/linux/pull_request/grpc_interop_toprod.cfg
+++ b/tools/internal_ci/linux/pull_request/grpc_interop_toprod.cfg
@@ -26,5 +26,5 @@
env_vars {
key: "RUN_TESTS_FLAGS"
- value: "-l all --allow_flakes --cloud_to_prod --cloud_to_prod_auth --prod_servers default gateway_v4 --use_docker --internal_ci -t -j 12"
+ value: "-l all --cloud_to_prod --cloud_to_prod_auth --prod_servers default gateway_v4 --use_docker --internal_ci -t -j 12"
}
diff --git a/tools/internal_ci/linux/grpc_sanity_webhook_test.cfg b/tools/internal_ci/linux/pull_request/grpc_sanity.cfg
similarity index 89%
rename from tools/internal_ci/linux/grpc_sanity_webhook_test.cfg
rename to tools/internal_ci/linux/pull_request/grpc_sanity.cfg
index 24e7984..0f83299 100644
--- a/tools/internal_ci/linux/grpc_sanity_webhook_test.cfg
+++ b/tools/internal_ci/linux/pull_request/grpc_sanity.cfg
@@ -16,7 +16,7 @@
# Location of the continuous shell script in repository.
build_file: "grpc/tools/internal_ci/linux/grpc_run_tests_matrix.sh"
-timeout_mins: 20
+timeout_mins: 40
action {
define_artifacts {
regex: "**/*sponge_log.xml"
@@ -26,5 +26,5 @@
env_vars {
key: "RUN_TESTS_FLAGS"
- value: "-f basictests linux sanity opt --inner_jobs 16 -j 1 --internal_ci"
+ value: "-f basictests linux sanity --inner_jobs 16 -j 1 --internal_ci"
}
diff --git a/tools/internal_ci/linux/grpc_sanity_webhook_test.cfg b/tools/internal_ci/macos/grpc_interop_toprod.cfg
similarity index 73%
copy from tools/internal_ci/linux/grpc_sanity_webhook_test.cfg
copy to tools/internal_ci/macos/grpc_interop_toprod.cfg
index 24e7984..c92c397 100644
--- a/tools/internal_ci/linux/grpc_sanity_webhook_test.cfg
+++ b/tools/internal_ci/macos/grpc_interop_toprod.cfg
@@ -15,16 +15,13 @@
# Config file for the internal CI (in protobuf text format)
# Location of the continuous shell script in repository.
-build_file: "grpc/tools/internal_ci/linux/grpc_run_tests_matrix.sh"
-timeout_mins: 20
+build_file: "grpc/tools/internal_ci/macos/grpc_interop_toprod.sh"
+gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json"
+gfile_resources: "/bigstore/grpc-testing-secrets/interop/service_account/GrpcTesting-726eb1347f15.json"
+timeout_mins: 240
action {
define_artifacts {
regex: "**/*sponge_log.xml"
regex: "github/grpc/reports/**"
}
}
-
-env_vars {
- key: "RUN_TESTS_FLAGS"
- value: "-f basictests linux sanity opt --inner_jobs 16 -j 1 --internal_ci"
-}
diff --git a/tools/internal_ci/macos/grpc_interop_toprod.sh b/tools/internal_ci/macos/grpc_interop_toprod.sh
new file mode 100755
index 0000000..819a472
--- /dev/null
+++ b/tools/internal_ci/macos/grpc_interop_toprod.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+# 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.
+
+set -ex
+
+# change to grpc repo root
+cd $(dirname $0)/../../..
+
+source tools/internal_ci/helper_scripts/prepare_build_macos_interop_rc
+source tools/internal_ci/helper_scripts/prepare_build_macos_rc
+
+# using run_interop_tests.py without --use_docker, so we need to build first
+tools/run_tests/run_tests.py -l c++ -c opt --build_only
+
+export GRPC_DEFAULT_SSL_ROOTS_FILE_PATH="$(pwd)/etc/roots.pem"
+
+# NOTE: only tests a subset of languages for time & dependency constraints
+# building all languages in the same working copy can also lead to conflicts
+# due to different compilation flags
+tools/run_tests/run_interop_tests.py -l c++ \
+ --cloud_to_prod --cloud_to_prod_auth --prod_servers default gateway_v4 \
+ --service_account_key_file="${KOKORO_GFILE_DIR}/GrpcTesting-726eb1347f15.json" \
+ --skip_compute_engine_creds --internal_ci -t -j 4
diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py
index aa45f7f..e39fabe 100644
--- a/tools/interop_matrix/client_matrix.py
+++ b/tools/interop_matrix/client_matrix.py
@@ -87,6 +87,9 @@
{
'v1.10.0': None
},
+ {
+ 'v1.11.0': None
+ },
],
'go': [
{
@@ -117,7 +120,10 @@
'v1.9.2': None
},
{
- 'v1.10.0': None
+ 'v1.10.1': None
+ },
+ {
+ 'v1.11.3': None
},
],
'java': [
@@ -154,6 +160,9 @@
{
'v1.10.1': None
},
+ {
+ 'v1.11.0': None
+ },
],
'python': [
{
@@ -186,6 +195,9 @@
{
'v1.10.0': None
},
+ {
+ 'v1.11.0': None
+ },
],
'node': [
{
@@ -256,6 +268,9 @@
{
'v1.10.0': None
},
+ {
+ 'v1.11.0': None
+ },
],
'php': [
{
@@ -288,6 +303,9 @@
{
'v1.10.0': None
},
+ {
+ 'v1.11.0': None
+ },
],
'csharp': [
#{'v1.0.1': None},
@@ -318,6 +336,9 @@
{
'v1.10.0': None
},
+ {
+ 'v1.11.0': None
+ },
],
}
@@ -337,4 +358,14 @@
'ruby_v1.0.1': 'ruby__v1.0.1',
'csharp_v1.1.4': 'csharp__v1.1.4',
'csharp_v1.2.5': 'csharp__v1.1.4',
+ 'python_v1.0.x': 'python__v1.0.x',
+ 'python_v1.1.4': 'python__v1.0.x',
+ 'python_v1.2.5': 'python__v1.0.x',
+ 'python_v1.3.9': 'python__v1.0.x',
+ 'python_v1.4.2': 'python__v1.0.x',
+ 'python_v1.6.6': 'python__v1.0.x',
+ 'python_v1.7.2': 'python__v1.0.x',
+ 'python_v1.8.1': 'python__v1.0.x',
+ 'python_v1.9.1': 'python__v1.0.x',
+ 'python_v1.10.0': 'python__v1.0.x',
}
diff --git a/tools/interop_matrix/testcases/python__master b/tools/interop_matrix/testcases/python__master
index 71ba75e..467e41f 100755
--- a/tools/interop_matrix/testcases/python__master
+++ b/tools/interop_matrix/testcases/python__master
@@ -1,20 +1,20 @@
#!/bin/bash
echo "Testing ${docker_image:=grpc_interop_python:797ca293-94e8-48d4-92e9-a4d52fcfcca9}"
-docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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\""
diff --git a/tools/interop_matrix/testcases/python__v1.0.x b/tools/interop_matrix/testcases/python__v1.0.x
new file mode 100755
index 0000000..71ba75e
--- /dev/null
+++ b/tools/interop_matrix/testcases/python__v1.0.x
@@ -0,0 +1,20 @@
+#!/bin/bash
+echo "Testing ${docker_image:=grpc_interop_python:797ca293-94e8-48d4-92e9-a4d52fcfcca9}"
+docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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 -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--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\""
diff --git a/tools/profiling/microbenchmarks/bm2bq.py b/tools/profiling/microbenchmarks/bm2bq.py
index e084e28..c5307c5 100755
--- a/tools/profiling/microbenchmarks/bm2bq.py
+++ b/tools/profiling/microbenchmarks/bm2bq.py
@@ -1,9 +1,5 @@
#!/usr/bin/env python2.7
#
-# Convert google-benchmark json output to something that can be uploaded to
-# BigQuery
-#
-#
# Copyright 2017 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,6 +14,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+# Convert google-benchmark json output to something that can be uploaded to
+# BigQuery
+
import sys
import json
import csv
@@ -54,6 +53,7 @@
else:
js2 = None
+# TODO(jtattermusch): write directly to a file instead of stdout
writer = csv.DictWriter(sys.stdout, [c for c, t in columns])
for row in bm_json.expand_json(js, js2):
diff --git a/tools/profiling/microbenchmarks/bm_diff/bm_constants.py b/tools/profiling/microbenchmarks/bm_diff/bm_constants.py
index 5719e42..c8b6c1e 100644
--- a/tools/profiling/microbenchmarks/bm_diff/bm_constants.py
+++ b/tools/profiling/microbenchmarks/bm_diff/bm_constants.py
@@ -22,11 +22,10 @@
'bm_metadata', 'bm_fullstack_trickle'
]
-_INTERESTING = ('cpu_time', 'real_time', 'call_initial_size-median',
- 'locks_per_iteration', 'allocs_per_iteration',
- 'writes_per_iteration', 'atm_cas_per_iteration',
- 'atm_add_per_iteration', 'nows_per_iteration',
- 'cli_transport_stalls_per_iteration',
+_INTERESTING = ('cpu_time', 'real_time', 'locks_per_iteration',
+ 'allocs_per_iteration', 'writes_per_iteration',
+ 'atm_cas_per_iteration', 'atm_add_per_iteration',
+ 'nows_per_iteration', 'cli_transport_stalls_per_iteration',
'cli_stream_stalls_per_iteration',
'svr_transport_stalls_per_iteration',
'svr_stream_stalls_per_iteration',
diff --git a/tools/profiling/microbenchmarks/bm_json.py b/tools/profiling/microbenchmarks/bm_json.py
index 497d7ca..2f5eb70 100644
--- a/tools/profiling/microbenchmarks/bm_json.py
+++ b/tools/profiling/microbenchmarks/bm_json.py
@@ -12,8 +12,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+# Utilities for manipulating JSON data that represents microbenchmark results.
+
import os
+# template arguments and dynamic arguments of individual benchmark types
+# Example benchmark name: "BM_UnaryPingPong<TCP, NoOpMutator, NoOpMutator>/0/0"
_BM_SPECS = {
'BM_UnaryPingPong': {
'tpl': ['fixture', 'client_mutator', 'server_mutator'],
@@ -115,6 +119,7 @@
def numericalize(s):
+ """Convert abbreviations like '100M' or '10k' to a number."""
if not s: return ''
if s[-1] == 'k':
return float(s[:-1]) * 1024
@@ -159,9 +164,6 @@
rest = s[0]
dyn_args = s[1:]
name = rest
- print(name)
- print(dyn_args, _BM_SPECS[name]['dyn'])
- print(tpl_args, _BM_SPECS[name]['tpl'])
assert name in _BM_SPECS, '_BM_SPECS needs to be expanded for %s' % name
assert len(dyn_args) == len(_BM_SPECS[name]['dyn'])
assert len(tpl_args) == len(_BM_SPECS[name]['tpl'])
diff --git a/tools/run_tests/README.md b/tools/run_tests/README.md
index 60f2074..64d67e4 100644
--- a/tools/run_tests/README.md
+++ b/tools/run_tests/README.md
@@ -14,6 +14,12 @@
- `--use_docker` Builds a docker container containing all the prerequisites for given language and runs the tests under that container.
- `--build_only` Only build, do not run the tests.
+Note: If you get an error such as `ImportError: No module named httplib2`, then you may be missing some Python modules. Install the module listed in the error and try again.
+
+Note: some tests may be flaky. Check the "Issues" tab for known flakes and other issues.
+
+The full suite of unit tests will take many minutes to run.
+
# Interop tests (run_interop_tests.py)
Runs tests for cross-platform/cross-language interoperability. For more details, see [Interop tests descriptions](/doc/interop-test-descriptions.md)
diff --git a/tools/run_tests/artifacts/artifact_targets.py b/tools/run_tests/artifacts/artifact_targets.py
index daa163e..e4d9e6b 100644
--- a/tools/run_tests/artifacts/artifact_targets.py
+++ b/tools/run_tests/artifacts/artifact_targets.py
@@ -222,7 +222,13 @@
return []
def build_jobspec(self):
- if self.platform == 'windows':
+ if self.arch == 'android':
+ return create_docker_jobspec(
+ self.name,
+ 'tools/dockerfile/grpc_artifact_android_ndk',
+ 'tools/run_tests/artifacts/build_artifact_csharp_android.sh',
+ environ={})
+ elif self.platform == 'windows':
cmake_arch_option = 'Win32' if self.arch == 'x86' else self.arch
return create_jobspec(
self.name, [
@@ -342,6 +348,7 @@
for Cls in (CSharpExtArtifact, ProtocArtifact)
for platform in ('linux', 'macos', 'windows') for arch in ('x86', 'x64')
] + [
+ CSharpExtArtifact('linux', 'android'),
PythonArtifact('linux', 'x86', 'cp27-cp27m'),
PythonArtifact('linux', 'x86', 'cp27-cp27mu'),
PythonArtifact('linux', 'x86', 'cp34-cp34m'),
diff --git a/tools/run_tests/artifacts/build_artifact_csharp_android.sh b/tools/run_tests/artifacts/build_artifact_csharp_android.sh
new file mode 100755
index 0000000..ba598e7
--- /dev/null
+++ b/tools/run_tests/artifacts/build_artifact_csharp_android.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+# 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.
+
+set -ex
+
+cd "$(dirname "$0")/../../.."
+
+src/csharp/experimental/build_native_ext_for_android.sh
+
+mkdir -p "${ARTIFACTS_OUT}"
+cp cmake/build/libgrpc_csharp_ext.so "${ARTIFACTS_OUT}"
diff --git a/tools/run_tests/artifacts/build_artifact_python.sh b/tools/run_tests/artifacts/build_artifact_python.sh
index 9ea0f05..cd794a1 100755
--- a/tools/run_tests/artifacts/build_artifact_python.sh
+++ b/tools/run_tests/artifacts/build_artifact_python.sh
@@ -17,7 +17,6 @@
cd "$(dirname "$0")/../../.."
-export GRPC_PYTHON_USE_CUSTOM_BDIST=0
export GRPC_PYTHON_BUILD_WITH_CYTHON=1
export PYTHON=${PYTHON:-python}
export PIP=${PIP:-pip}
diff --git a/tools/run_tests/artifacts/build_package_ruby.sh b/tools/run_tests/artifacts/build_package_ruby.sh
index 05eacd4..4f74f08 100755
--- a/tools/run_tests/artifacts/build_package_ruby.sh
+++ b/tools/run_tests/artifacts/build_package_ruby.sh
@@ -53,8 +53,11 @@
output_dir="$base/src/ruby/tools/bin/${ruby_arch}-${plat}"
mkdir -p "$output_dir"/google/protobuf
mkdir -p "$output_dir"/google/protobuf/compiler # needed for plugin.proto
- cp "$input_dir"/protoc* "$output_dir"/
- cp "$input_dir"/grpc_ruby_plugin* "$output_dir"/
+ cp "$input_dir"/protoc* "$input_dir"/grpc_ruby_plugin* "$output_dir/"
+ if [[ "$plat" != "windows" ]]
+ then
+ chmod +x "$output_dir/protoc" "$output_dir/grpc_ruby_plugin"
+ fi
for proto in "${well_known_protos[@]}"; do
cp "$base/third_party/protobuf/src/google/protobuf/$proto.proto" "$output_dir/google/protobuf/$proto.proto"
done
diff --git a/tools/run_tests/artifacts/distribtest_targets.py b/tools/run_tests/artifacts/distribtest_targets.py
index 041faab..80adc20 100644
--- a/tools/run_tests/artifacts/distribtest_targets.py
+++ b/tools/run_tests/artifacts/distribtest_targets.py
@@ -146,8 +146,12 @@
class PythonDistribTest(object):
"""Tests Python package"""
- def __init__(self, platform, arch, docker_suffix):
- self.name = 'python_%s_%s_%s' % (platform, arch, docker_suffix)
+ def __init__(self, platform, arch, docker_suffix, source=False):
+ self.source = source
+ if source:
+ self.name = 'python_dev_%s_%s_%s' % (platform, arch, docker_suffix)
+ else:
+ self.name = 'python_%s_%s_%s' % (platform, arch, docker_suffix)
self.platform = platform
self.arch = arch
self.docker_suffix = docker_suffix
@@ -160,12 +164,20 @@
if not self.platform == 'linux':
raise Exception("Not supported yet.")
- return create_docker_jobspec(
- self.name,
- 'tools/dockerfile/distribtest/python_%s_%s' % (self.docker_suffix,
- self.arch),
- 'test/distrib/python/run_distrib_test.sh',
- copy_rel_path='test/distrib')
+ if self.source:
+ return create_docker_jobspec(
+ self.name,
+ 'tools/dockerfile/distribtest/python_dev_%s_%s' %
+ (self.docker_suffix, self.arch),
+ 'test/distrib/python/run_source_distrib_test.sh',
+ copy_rel_path='test/distrib')
+ else:
+ return create_docker_jobspec(
+ self.name,
+ 'tools/dockerfile/distribtest/python_%s_%s' %
+ (self.docker_suffix, self.arch),
+ 'test/distrib/python/run_binary_distrib_test.sh',
+ copy_rel_path='test/distrib')
def __str__(self):
return self.name
@@ -287,7 +299,10 @@
return [
CppDistribTest('linux', 'x64', 'jessie', 'routeguide'),
CppDistribTest('linux', 'x64', 'jessie', 'cmake'),
+ CppDistribTest('linux', 'x64', 'jessie', 'cmake_as_externalproject'),
+ CppDistribTest('linux', 'x64', 'jessie', 'cmake_as_submodule'),
CppDistribTest('windows', 'x86', testcase='cmake'),
+ CppDistribTest('windows', 'x86', testcase='cmake_as_externalproject'),
CSharpDistribTest('linux', 'x64', 'wheezy'),
CSharpDistribTest('linux', 'x64', 'jessie'),
CSharpDistribTest('linux', 'x86', 'jessie'),
@@ -312,6 +327,14 @@
PythonDistribTest('linux', 'x64', 'ubuntu1204'),
PythonDistribTest('linux', 'x64', 'ubuntu1404'),
PythonDistribTest('linux', 'x64', 'ubuntu1604'),
+ PythonDistribTest('linux', 'x64', 'jessie', source=True),
+ PythonDistribTest('linux', 'x86', 'jessie', source=True),
+ PythonDistribTest('linux', 'x64', 'centos7', source=True),
+ PythonDistribTest('linux', 'x64', 'fedora22', source=True),
+ PythonDistribTest('linux', 'x64', 'fedora23', source=True),
+ PythonDistribTest('linux', 'x64', 'arch', source=True),
+ PythonDistribTest('linux', 'x64', 'ubuntu1404', source=True),
+ PythonDistribTest('linux', 'x64', 'ubuntu1604', source=True),
RubyDistribTest('linux', 'x64', 'wheezy'),
RubyDistribTest('linux', 'x64', 'jessie'),
RubyDistribTest('linux', 'x86', 'jessie'),
diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json
index fd6c526..4f0fc1d 100644
--- a/tools/run_tests/generated/sources_and_headers.json
+++ b/tools/run_tests/generated/sources_and_headers.json
@@ -60,6 +60,23 @@
"headers": [],
"is_filegroup": false,
"language": "c",
+ "name": "alts_credentials_fuzzer",
+ "src": [
+ "test/core/security/alts_credentials_fuzzer.cc"
+ ],
+ "third_party": false,
+ "type": "target"
+ },
+ {
+ "deps": [
+ "gpr",
+ "gpr_test_util",
+ "grpc",
+ "grpc_test_util"
+ ],
+ "headers": [],
+ "is_filegroup": false,
+ "language": "c",
"name": "api_fuzzer",
"src": [
"test/core/end2end/fuzzers/api_fuzzer.cc"
@@ -993,23 +1010,6 @@
"headers": [],
"is_filegroup": false,
"language": "c",
- "name": "grpc_invalid_channel_args_test",
- "src": [
- "test/core/surface/invalid_channel_args_test.cc"
- ],
- "third_party": false,
- "type": "target"
- },
- {
- "deps": [
- "gpr",
- "gpr_test_util",
- "grpc",
- "grpc_test_util"
- ],
- "headers": [],
- "is_filegroup": false,
- "language": "c",
"name": "grpc_json_token_test",
"src": [
"test/core/security/json_token_test.cc"
@@ -2686,6 +2686,7 @@
"benchmark",
"gpr",
"gpr_test_util",
+ "grpc++_test_config",
"grpc++_test_util_unsecure",
"grpc++_unsecure",
"grpc_benchmark",
@@ -2707,6 +2708,7 @@
"benchmark",
"gpr",
"gpr_test_util",
+ "grpc++_test_config",
"grpc++_test_util_unsecure",
"grpc++_unsecure",
"grpc_benchmark",
@@ -2728,6 +2730,7 @@
"benchmark",
"gpr",
"gpr_test_util",
+ "grpc++_test_config",
"grpc++_test_util_unsecure",
"grpc++_unsecure",
"grpc_benchmark",
@@ -2749,6 +2752,7 @@
"benchmark",
"gpr",
"gpr_test_util",
+ "grpc++_test_config",
"grpc++_test_util_unsecure",
"grpc++_unsecure",
"grpc_benchmark",
@@ -2770,6 +2774,7 @@
"benchmark",
"gpr",
"gpr_test_util",
+ "grpc++_test_config",
"grpc++_test_util_unsecure",
"grpc++_unsecure",
"grpc_benchmark",
@@ -2791,6 +2796,7 @@
"benchmark",
"gpr",
"gpr_test_util",
+ "grpc++_test_config",
"grpc++_test_util_unsecure",
"grpc++_unsecure",
"grpc_benchmark",
@@ -2812,6 +2818,7 @@
"benchmark",
"gpr",
"gpr_test_util",
+ "grpc++_test_config",
"grpc++_test_util_unsecure",
"grpc++_unsecure",
"grpc_benchmark",
@@ -2833,6 +2840,7 @@
"benchmark",
"gpr",
"gpr_test_util",
+ "grpc++_test_config",
"grpc++_test_util_unsecure",
"grpc++_unsecure",
"grpc_benchmark",
@@ -2854,6 +2862,7 @@
"benchmark",
"gpr",
"gpr_test_util",
+ "grpc++_test_config",
"grpc++_test_util_unsecure",
"grpc++_unsecure",
"grpc_benchmark",
@@ -2878,6 +2887,7 @@
"benchmark",
"gpr",
"gpr_test_util",
+ "grpc++_test_config",
"grpc++_test_util_unsecure",
"grpc++_unsecure",
"grpc_benchmark",
@@ -2924,6 +2934,7 @@
"benchmark",
"gpr",
"gpr_test_util",
+ "grpc++_test_config",
"grpc++_test_util_unsecure",
"grpc++_unsecure",
"grpc_benchmark",
@@ -2948,6 +2959,7 @@
"benchmark",
"gpr",
"gpr_test_util",
+ "grpc++_test_config",
"grpc++_test_util_unsecure",
"grpc++_unsecure",
"grpc_benchmark",
@@ -2969,6 +2981,7 @@
"benchmark",
"gpr",
"gpr_test_util",
+ "grpc++_test_config",
"grpc++_test_util_unsecure",
"grpc++_unsecure",
"grpc_benchmark",
@@ -3211,6 +3224,9 @@
"grpc++_core_stats"
],
"headers": [
+ "src/proto/grpc/testing/benchmark_service.grpc.pb.h",
+ "src/proto/grpc/testing/benchmark_service.pb.h",
+ "src/proto/grpc/testing/benchmark_service_mock.grpc.pb.h",
"src/proto/grpc/testing/control.grpc.pb.h",
"src/proto/grpc/testing/control.pb.h",
"src/proto/grpc/testing/control_mock.grpc.pb.h",
@@ -3220,12 +3236,15 @@
"src/proto/grpc/testing/payloads.grpc.pb.h",
"src/proto/grpc/testing/payloads.pb.h",
"src/proto/grpc/testing/payloads_mock.grpc.pb.h",
- "src/proto/grpc/testing/services.grpc.pb.h",
- "src/proto/grpc/testing/services.pb.h",
- "src/proto/grpc/testing/services_mock.grpc.pb.h",
+ "src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.h",
+ "src/proto/grpc/testing/report_qps_scenario_service.pb.h",
+ "src/proto/grpc/testing/report_qps_scenario_service_mock.grpc.pb.h",
"src/proto/grpc/testing/stats.grpc.pb.h",
"src/proto/grpc/testing/stats.pb.h",
- "src/proto/grpc/testing/stats_mock.grpc.pb.h"
+ "src/proto/grpc/testing/stats_mock.grpc.pb.h",
+ "src/proto/grpc/testing/worker_service.grpc.pb.h",
+ "src/proto/grpc/testing/worker_service.pb.h",
+ "src/proto/grpc/testing/worker_service_mock.grpc.pb.h"
],
"is_filegroup": false,
"language": "c++",
@@ -3245,6 +3264,9 @@
"grpc++_core_stats"
],
"headers": [
+ "src/proto/grpc/testing/benchmark_service.grpc.pb.h",
+ "src/proto/grpc/testing/benchmark_service.pb.h",
+ "src/proto/grpc/testing/benchmark_service_mock.grpc.pb.h",
"src/proto/grpc/testing/control.grpc.pb.h",
"src/proto/grpc/testing/control.pb.h",
"src/proto/grpc/testing/control_mock.grpc.pb.h",
@@ -3254,12 +3276,15 @@
"src/proto/grpc/testing/payloads.grpc.pb.h",
"src/proto/grpc/testing/payloads.pb.h",
"src/proto/grpc/testing/payloads_mock.grpc.pb.h",
- "src/proto/grpc/testing/services.grpc.pb.h",
- "src/proto/grpc/testing/services.pb.h",
- "src/proto/grpc/testing/services_mock.grpc.pb.h",
+ "src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.h",
+ "src/proto/grpc/testing/report_qps_scenario_service.pb.h",
+ "src/proto/grpc/testing/report_qps_scenario_service_mock.grpc.pb.h",
"src/proto/grpc/testing/stats.grpc.pb.h",
"src/proto/grpc/testing/stats.pb.h",
- "src/proto/grpc/testing/stats_mock.grpc.pb.h"
+ "src/proto/grpc/testing/stats_mock.grpc.pb.h",
+ "src/proto/grpc/testing/worker_service.grpc.pb.h",
+ "src/proto/grpc/testing/worker_service.pb.h",
+ "src/proto/grpc/testing/worker_service_mock.grpc.pb.h"
],
"is_filegroup": false,
"language": "c++",
@@ -3901,6 +3926,26 @@
"gpr_test_util",
"grpc",
"grpc++",
+ "grpc++_test_util",
+ "grpc_test_util",
+ "lb_load_data_store"
+ ],
+ "headers": [],
+ "is_filegroup": false,
+ "language": "c++",
+ "name": "lb_load_data_store_test",
+ "src": [
+ "test/cpp/server/load_reporter/load_data_store_test.cc"
+ ],
+ "third_party": false,
+ "type": "target"
+ },
+ {
+ "deps": [
+ "gpr",
+ "gpr_test_util",
+ "grpc",
+ "grpc++",
"grpc++_test",
"grpc_test_util"
],
@@ -4248,6 +4293,23 @@
"gpr",
"gpr_test_util",
"grpc",
+ "grpc_test_util"
+ ],
+ "headers": [],
+ "is_filegroup": false,
+ "language": "c++",
+ "name": "retry_throttle_test",
+ "src": [
+ "test/core/client_channel/retry_throttle_test.cc"
+ ],
+ "third_party": false,
+ "type": "target"
+ },
+ {
+ "deps": [
+ "gpr",
+ "gpr_test_util",
+ "grpc",
"grpc++",
"grpc++_test_util",
"grpc_test_util"
@@ -4333,6 +4395,32 @@
"deps": [
"gpr",
"gpr_test_util",
+ "grpc++_test_util_unsecure",
+ "grpc++_unsecure",
+ "grpc_test_util_unsecure",
+ "grpc_unsecure"
+ ],
+ "headers": [
+ "src/proto/grpc/testing/echo.grpc.pb.h",
+ "src/proto/grpc/testing/echo.pb.h",
+ "src/proto/grpc/testing/echo_messages.grpc.pb.h",
+ "src/proto/grpc/testing/echo_messages.pb.h",
+ "src/proto/grpc/testing/echo_messages_mock.grpc.pb.h",
+ "src/proto/grpc/testing/echo_mock.grpc.pb.h"
+ ],
+ "is_filegroup": false,
+ "language": "c++",
+ "name": "server_builder_with_socket_mutator_test",
+ "src": [
+ "test/cpp/server/server_builder_with_socket_mutator_test.cc"
+ ],
+ "third_party": false,
+ "type": "target"
+ },
+ {
+ "deps": [
+ "gpr",
+ "gpr_test_util",
"grpc",
"grpc++",
"grpc++_test",
@@ -6414,6 +6502,24 @@
"headers": [],
"is_filegroup": false,
"language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "src": [
+ "test/core/security/alts_credentials_fuzzer.cc",
+ "test/core/util/one_corpus_entry_fuzzer.cc"
+ ],
+ "third_party": false,
+ "type": "target"
+ },
+ {
+ "deps": [
+ "gpr",
+ "gpr_test_util",
+ "grpc",
+ "grpc_test_util"
+ ],
+ "headers": [],
+ "is_filegroup": false,
+ "language": "c",
"name": "api_fuzzer_one_entry",
"src": [
"test/core/end2end/fuzzers/api_fuzzer.cc",
@@ -6705,6 +6811,7 @@
"census",
"gpr",
"grpc_base",
+ "grpc_client_authority_filter",
"grpc_deadline_filter",
"grpc_lb_policy_grpclb_secure",
"grpc_lb_policy_pick_first",
@@ -6739,16 +6846,8 @@
"deps": [
"gpr",
"grpc_base",
- "grpc_base_headers",
- "grpc_deadline_filter",
- "grpc_lb_policy_pick_first",
- "grpc_max_age_filter",
- "grpc_message_size_filter",
- "grpc_resolver_dns_native",
- "grpc_resolver_sockaddr",
"grpc_server_load_reporting",
"grpc_transport_chttp2_client_secure",
- "grpc_transport_chttp2_server_secure",
"grpc_transport_cronet_client_secure"
],
"headers": [],
@@ -6820,6 +6919,7 @@
"census",
"gpr",
"grpc_base",
+ "grpc_client_authority_filter",
"grpc_deadline_filter",
"grpc_lb_policy_grpclb",
"grpc_lb_policy_pick_first",
@@ -7450,6 +7550,23 @@
},
{
"deps": [
+ "grpc++"
+ ],
+ "headers": [
+ "src/cpp/server/load_reporter/load_data_store.h"
+ ],
+ "is_filegroup": false,
+ "language": "c++",
+ "name": "lb_load_data_store",
+ "src": [
+ "src/cpp/server/load_reporter/load_data_store.cc",
+ "src/cpp/server/load_reporter/load_data_store.h"
+ ],
+ "third_party": false,
+ "type": "lib"
+ },
+ {
+ "deps": [
"grpc",
"grpc++",
"grpc++_core_stats",
@@ -7457,6 +7574,9 @@
"grpc_test_util"
],
"headers": [
+ "src/proto/grpc/testing/benchmark_service.grpc.pb.h",
+ "src/proto/grpc/testing/benchmark_service.pb.h",
+ "src/proto/grpc/testing/benchmark_service_mock.grpc.pb.h",
"src/proto/grpc/testing/control.grpc.pb.h",
"src/proto/grpc/testing/control.pb.h",
"src/proto/grpc/testing/control_mock.grpc.pb.h",
@@ -7466,12 +7586,15 @@
"src/proto/grpc/testing/payloads.grpc.pb.h",
"src/proto/grpc/testing/payloads.pb.h",
"src/proto/grpc/testing/payloads_mock.grpc.pb.h",
- "src/proto/grpc/testing/services.grpc.pb.h",
- "src/proto/grpc/testing/services.pb.h",
- "src/proto/grpc/testing/services_mock.grpc.pb.h",
+ "src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.h",
+ "src/proto/grpc/testing/report_qps_scenario_service.pb.h",
+ "src/proto/grpc/testing/report_qps_scenario_service_mock.grpc.pb.h",
"src/proto/grpc/testing/stats.grpc.pb.h",
"src/proto/grpc/testing/stats.pb.h",
"src/proto/grpc/testing/stats_mock.grpc.pb.h",
+ "src/proto/grpc/testing/worker_service.grpc.pb.h",
+ "src/proto/grpc/testing/worker_service.pb.h",
+ "src/proto/grpc/testing/worker_service_mock.grpc.pb.h",
"test/cpp/qps/benchmark_config.h",
"test/cpp/qps/client.h",
"test/cpp/qps/driver.h",
@@ -8524,6 +8647,7 @@
"test/core/end2end/tests/bad_ping.cc",
"test/core/end2end/tests/binary_metadata.cc",
"test/core/end2end/tests/call_creds.cc",
+ "test/core/end2end/tests/call_host_override.cc",
"test/core/end2end/tests/cancel_after_accept.cc",
"test/core/end2end/tests/cancel_after_client_done.cc",
"test/core/end2end/tests/cancel_after_invoke.cc",
@@ -8571,6 +8695,7 @@
"test/core/end2end/tests/retry_exceeds_buffer_size_in_initial_batch.cc",
"test/core/end2end/tests/retry_exceeds_buffer_size_in_subsequent_batch.cc",
"test/core/end2end/tests/retry_non_retriable_status.cc",
+ "test/core/end2end/tests/retry_non_retriable_status_before_recv_trailing_metadata_started.cc",
"test/core/end2end/tests/retry_recv_initial_metadata.cc",
"test/core/end2end/tests/retry_recv_message.cc",
"test/core/end2end/tests/retry_server_pushback_delay.cc",
@@ -8621,6 +8746,7 @@
"test/core/end2end/tests/bad_hostname.cc",
"test/core/end2end/tests/bad_ping.cc",
"test/core/end2end/tests/binary_metadata.cc",
+ "test/core/end2end/tests/call_host_override.cc",
"test/core/end2end/tests/cancel_after_accept.cc",
"test/core/end2end/tests/cancel_after_client_done.cc",
"test/core/end2end/tests/cancel_after_invoke.cc",
@@ -8668,6 +8794,7 @@
"test/core/end2end/tests/retry_exceeds_buffer_size_in_initial_batch.cc",
"test/core/end2end/tests/retry_exceeds_buffer_size_in_subsequent_batch.cc",
"test/core/end2end/tests/retry_non_retriable_status.cc",
+ "test/core/end2end/tests/retry_non_retriable_status_before_recv_trailing_metadata_started.cc",
"test/core/end2end/tests/retry_recv_initial_metadata.cc",
"test/core/end2end/tests/retry_recv_message.cc",
"test/core/end2end/tests/retry_server_pushback_delay.cc",
@@ -8796,6 +8923,7 @@
"tsi_interface"
],
"headers": [
+ "include/grpc/grpc_security.h",
"src/core/lib/security/credentials/alts/check_gcp_environment.h",
"src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h",
"src/core/tsi/alts/handshaker/alts_handshaker_service_api.h",
@@ -8807,6 +8935,7 @@
"language": "c",
"name": "alts_util",
"src": [
+ "include/grpc/grpc_security.h",
"src/core/lib/security/credentials/alts/check_gcp_environment.cc",
"src/core/lib/security/credentials/alts/check_gcp_environment.h",
"src/core/lib/security/credentials/alts/check_gcp_environment_linux.cc",
@@ -9551,6 +9680,24 @@
{
"deps": [
"gpr",
+ "grpc_base"
+ ],
+ "headers": [
+ "src/core/ext/filters/http/client_authority_filter.h"
+ ],
+ "is_filegroup": true,
+ "language": "c",
+ "name": "grpc_client_authority_filter",
+ "src": [
+ "src/core/ext/filters/http/client_authority_filter.cc",
+ "src/core/ext/filters/http/client_authority_filter.h"
+ ],
+ "third_party": false,
+ "type": "filegroup"
+ },
+ {
+ "deps": [
+ "gpr",
"grpc_base",
"grpc_deadline_filter"
],
@@ -9708,6 +9855,7 @@
],
"headers": [
"src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h",
+ "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h",
@@ -9720,6 +9868,7 @@
"src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc",
"src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc",
+ "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc",
@@ -9743,6 +9892,7 @@
],
"headers": [
"src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h",
+ "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h",
@@ -9755,6 +9905,7 @@
"src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc",
"src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc",
+ "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc",
@@ -9814,7 +9965,6 @@
"language": "c",
"name": "grpc_lb_subchannel_list",
"src": [
- "src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc",
"src/core/ext/filters/client_channel/lb_policy/subchannel_list.h"
],
"third_party": false,
@@ -9941,6 +10091,7 @@
],
"headers": [
"include/grpc/grpc_security.h",
+ "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h",
"src/core/lib/security/context/security_context.h",
"src/core/lib/security/credentials/alts/alts_credentials.h",
"src/core/lib/security/credentials/composite/composite_credentials.h",
@@ -9968,6 +10119,7 @@
"name": "grpc_secure",
"src": [
"include/grpc/grpc_security.h",
+ "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h",
"src/core/lib/http/httpcli_security_connector.cc",
"src/core/lib/security/context/security_context.cc",
"src/core/lib/security/context/security_context.h",
@@ -10074,6 +10226,7 @@
"test/core/end2end/fixtures/proxy.h",
"test/core/iomgr/endpoint_tests.h",
"test/core/util/debugger_macros.h",
+ "test/core/util/fuzzer_util.h",
"test/core/util/grpc_profiler.h",
"test/core/util/histogram.h",
"test/core/util/memory_counters.h",
@@ -10103,6 +10256,8 @@
"test/core/iomgr/endpoint_tests.h",
"test/core/util/debugger_macros.cc",
"test/core/util/debugger_macros.h",
+ "test/core/util/fuzzer_util.cc",
+ "test/core/util/fuzzer_util.h",
"test/core/util/grpc_profiler.cc",
"test/core/util/grpc_profiler.h",
"test/core/util/histogram.cc",
@@ -10269,12 +10424,15 @@
"grpc_transport_chttp2"
],
"headers": [
+ "src/core/ext/transport/chttp2/client/authority.h",
"src/core/ext/transport/chttp2/client/chttp2_connector.h"
],
"is_filegroup": true,
"language": "c",
"name": "grpc_transport_chttp2_client_connector",
"src": [
+ "src/core/ext/transport/chttp2/client/authority.cc",
+ "src/core/ext/transport/chttp2/client/authority.h",
"src/core/ext/transport/chttp2/client/chttp2_connector.cc",
"src/core/ext/transport/chttp2/client/chttp2_connector.h"
],
@@ -10544,7 +10702,6 @@
],
"headers": [
"src/core/tsi/transport_security.h",
- "src/core/tsi/transport_security_adapter.h",
"src/core/tsi/transport_security_interface.h"
],
"is_filegroup": true,
@@ -10553,8 +10710,6 @@
"src": [
"src/core/tsi/transport_security.cc",
"src/core/tsi/transport_security.h",
- "src/core/tsi/transport_security_adapter.cc",
- "src/core/tsi/transport_security_adapter.h",
"src/core/tsi/transport_security_interface.h"
],
"third_party": false,
@@ -10729,6 +10884,8 @@
],
"headers": [
"include/grpc++/impl/codegen/proto_utils.h",
+ "include/grpcpp/impl/codegen/proto_buffer_reader.h",
+ "include/grpcpp/impl/codegen/proto_buffer_writer.h",
"include/grpcpp/impl/codegen/proto_utils.h"
],
"is_filegroup": true,
@@ -10736,6 +10893,8 @@
"name": "grpc++_codegen_proto",
"src": [
"include/grpc++/impl/codegen/proto_utils.h",
+ "include/grpcpp/impl/codegen/proto_buffer_reader.h",
+ "include/grpcpp/impl/codegen/proto_buffer_writer.h",
"include/grpcpp/impl/codegen/proto_utils.h"
],
"third_party": false,
@@ -10834,6 +10993,8 @@
"include/grpcpp/support/byte_buffer.h",
"include/grpcpp/support/channel_arguments.h",
"include/grpcpp/support/config.h",
+ "include/grpcpp/support/proto_buffer_reader.h",
+ "include/grpcpp/support/proto_buffer_writer.h",
"include/grpcpp/support/slice.h",
"include/grpcpp/support/status.h",
"include/grpcpp/support/status_code_enum.h",
@@ -10936,6 +11097,8 @@
"include/grpcpp/support/byte_buffer.h",
"include/grpcpp/support/channel_arguments.h",
"include/grpcpp/support/config.h",
+ "include/grpcpp/support/proto_buffer_reader.h",
+ "include/grpcpp/support/proto_buffer_writer.h",
"include/grpcpp/support/slice.h",
"include/grpcpp/support/status.h",
"include/grpcpp/support/status_code_enum.h",
@@ -10980,7 +11143,6 @@
"src/cpp/thread_manager/thread_manager.cc",
"src/cpp/thread_manager/thread_manager.h",
"src/cpp/util/byte_buffer_cc.cc",
- "src/cpp/util/slice_cc.cc",
"src/cpp/util/status.cc",
"src/cpp/util/string_ref.cc",
"src/cpp/util/time_cc.cc"
diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json
index c2bbf8c..701f44f 100644
--- a/tools/run_tests/generated/tests.json
+++ b/tools/run_tests/generated/tests.json
@@ -1279,30 +1279,6 @@
"ci_platforms": [
"linux",
"mac",
- "posix",
- "windows"
- ],
- "cpu_cost": 1.0,
- "exclude_configs": [],
- "exclude_iomgrs": [],
- "flaky": false,
- "gtest": false,
- "language": "c",
- "name": "grpc_invalid_channel_args_test",
- "platforms": [
- "linux",
- "mac",
- "posix",
- "windows"
- ],
- "uses_polling": false
- },
- {
- "args": [],
- "benchmark": false,
- "ci_platforms": [
- "linux",
- "mac",
"posix"
],
"cpu_cost": 1.0,
@@ -4428,6 +4404,30 @@
"flaky": false,
"gtest": true,
"language": "c++",
+ "name": "lb_load_data_store_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix",
+ "windows"
+ ],
+ "uses_polling": true
+ },
+ {
+ "args": [],
+ "benchmark": false,
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix",
+ "windows"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "gtest": true,
+ "language": "c++",
"name": "memory_test",
"platforms": [
"linux",
@@ -4666,6 +4666,30 @@
"flaky": false,
"gtest": true,
"language": "c++",
+ "name": "retry_throttle_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix",
+ "windows"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [],
+ "benchmark": false,
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix",
+ "windows"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "gtest": true,
+ "language": "c++",
"name": "secure_auth_context_test",
"platforms": [
"linux",
@@ -4749,6 +4773,24 @@
"args": [],
"benchmark": false,
"ci_platforms": [
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "gtest": true,
+ "language": "c++",
+ "name": "server_builder_with_socket_mutator_test",
+ "platforms": [
+ "posix"
+ ],
+ "uses_polling": true
+ },
+ {
+ "args": [],
+ "benchmark": false,
+ "ci_platforms": [
"linux",
"mac",
"posix",
@@ -6969,6 +7011,29 @@
},
{
"args": [
+ "call_host_override"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_census_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"cancel_after_accept"
],
"ci_platforms": [
@@ -8008,6 +8073,29 @@
},
{
"args": [
+ "retry_non_retriable_status_before_recv_trailing_metadata_started"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_census_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"retry_recv_initial_metadata"
],
"ci_platforms": [
@@ -8675,6 +8763,29 @@
},
{
"args": [
+ "call_host_override"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_compress_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"cancel_after_accept"
],
"ci_platforms": [
@@ -9691,6 +9802,29 @@
},
{
"args": [
+ "retry_non_retriable_status_before_recv_trailing_metadata_started"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_compress_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"retry_recv_initial_metadata"
],
"ci_platforms": [
@@ -10353,6 +10487,28 @@
},
{
"args": [
+ "call_host_override"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_fakesec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"cancel_after_accept"
],
"ci_platforms": [
@@ -11347,6 +11503,28 @@
},
{
"args": [
+ "retry_non_retriable_status_before_recv_trailing_metadata_started"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_fakesec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"retry_recv_initial_metadata"
],
"ci_platforms": [
@@ -13186,6 +13364,29 @@
},
{
"args": [
+ "call_host_override"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"cancel_after_accept"
],
"ci_platforms": [
@@ -14225,6 +14426,29 @@
},
{
"args": [
+ "retry_non_retriable_status_before_recv_trailing_metadata_started"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"retry_recv_initial_metadata"
],
"ci_platforms": [
@@ -14872,6 +15096,25 @@
},
{
"args": [
+ "call_host_override"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+pipe_test",
+ "platforms": [
+ "linux"
+ ]
+ },
+ {
+ "args": [
"cancel_after_accept"
],
"ci_platforms": [
@@ -15727,6 +15970,25 @@
},
{
"args": [
+ "retry_non_retriable_status_before_recv_trailing_metadata_started"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+pipe_test",
+ "platforms": [
+ "linux"
+ ]
+ },
+ {
+ "args": [
"retry_recv_initial_metadata"
],
"ci_platforms": [
@@ -16298,6 +16560,29 @@
},
{
"args": [
+ "call_host_override"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+trace_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"cancel_after_accept"
],
"ci_platforms": [
@@ -17291,6 +17576,29 @@
},
{
"args": [
+ "retry_non_retriable_status_before_recv_trailing_metadata_started"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+trace_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"retry_recv_initial_metadata"
],
"ci_platforms": [
@@ -17958,6 +18266,29 @@
},
{
"args": [
+ "call_host_override"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+workarounds_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"cancel_after_accept"
],
"ci_platforms": [
@@ -18997,6 +19328,29 @@
},
{
"args": [
+ "retry_non_retriable_status_before_recv_trailing_metadata_started"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+workarounds_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"retry_recv_initial_metadata"
],
"ci_platforms": [
@@ -19669,6 +20023,30 @@
},
{
"args": [
+ "call_host_override"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_http_proxy_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"cancel_after_accept"
],
"ci_platforms": [
@@ -20773,6 +21151,30 @@
},
{
"args": [
+ "retry_non_retriable_status_before_recv_trailing_metadata_started"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_http_proxy_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"retry_recv_initial_metadata"
],
"ci_platforms": [
@@ -21464,6 +21866,29 @@
},
{
"args": [
+ "call_host_override"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_load_reporting_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"cancel_after_accept"
],
"ci_platforms": [
@@ -22503,6 +22928,29 @@
},
{
"args": [
+ "retry_non_retriable_status_before_recv_trailing_metadata_started"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_load_reporting_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"retry_recv_initial_metadata"
],
"ci_platforms": [
@@ -23175,6 +23623,30 @@
},
{
"args": [
+ "call_host_override"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_oauth2_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"cancel_after_accept"
],
"ci_platforms": [
@@ -24255,6 +24727,30 @@
},
{
"args": [
+ "retry_non_retriable_status_before_recv_trailing_metadata_started"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_oauth2_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"retry_recv_initial_metadata"
],
"ci_platforms": [
@@ -24927,6 +25423,30 @@
},
{
"args": [
+ "call_host_override"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_proxy_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"cancel_after_accept"
],
"ci_platforms": [
@@ -29848,6 +30368,29 @@
},
{
"args": [
+ "call_host_override"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_ssl_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"cancel_after_accept"
],
"ci_platforms": [
@@ -30887,6 +31430,29 @@
},
{
"args": [
+ "retry_non_retriable_status_before_recv_trailing_metadata_started"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_ssl_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"retry_recv_initial_metadata"
],
"ci_platforms": [
@@ -31535,6 +32101,30 @@
},
{
"args": [
+ "call_host_override"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_ssl_proxy_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"cancel_after_accept"
],
"ci_platforms": [
@@ -33718,6 +34308,29 @@
},
{
"args": [
+ "retry_non_retriable_status_before_recv_trailing_metadata_started"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_uds_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"retry_recv_initial_metadata"
],
"ci_platforms": [
@@ -35305,6 +35918,29 @@
},
{
"args": [
+ "call_host_override"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_census_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"cancel_after_accept"
],
"ci_platforms": [
@@ -36344,6 +36980,29 @@
},
{
"args": [
+ "retry_non_retriable_status_before_recv_trailing_metadata_started"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_census_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"retry_recv_initial_metadata"
],
"ci_platforms": [
@@ -36988,6 +37647,29 @@
},
{
"args": [
+ "call_host_override"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_compress_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"cancel_after_accept"
],
"ci_platforms": [
@@ -38004,6 +38686,29 @@
},
{
"args": [
+ "retry_non_retriable_status_before_recv_trailing_metadata_started"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_compress_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"retry_recv_initial_metadata"
],
"ci_platforms": [
@@ -39821,6 +40526,29 @@
},
{
"args": [
+ "call_host_override"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"cancel_after_accept"
],
"ci_platforms": [
@@ -40860,6 +41588,29 @@
},
{
"args": [
+ "retry_non_retriable_status_before_recv_trailing_metadata_started"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"retry_recv_initial_metadata"
],
"ci_platforms": [
@@ -41488,6 +42239,25 @@
},
{
"args": [
+ "call_host_override"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+pipe_nosec_test",
+ "platforms": [
+ "linux"
+ ]
+ },
+ {
+ "args": [
"cancel_after_accept"
],
"ci_platforms": [
@@ -42343,6 +43113,25 @@
},
{
"args": [
+ "retry_non_retriable_status_before_recv_trailing_metadata_started"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+pipe_nosec_test",
+ "platforms": [
+ "linux"
+ ]
+ },
+ {
+ "args": [
"retry_recv_initial_metadata"
],
"ci_platforms": [
@@ -42891,6 +43680,29 @@
},
{
"args": [
+ "call_host_override"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+trace_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"cancel_after_accept"
],
"ci_platforms": [
@@ -43884,6 +44696,29 @@
},
{
"args": [
+ "retry_non_retriable_status_before_recv_trailing_metadata_started"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+trace_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"retry_recv_initial_metadata"
],
"ci_platforms": [
@@ -44528,6 +45363,29 @@
},
{
"args": [
+ "call_host_override"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+workarounds_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"cancel_after_accept"
],
"ci_platforms": [
@@ -45567,6 +46425,29 @@
},
{
"args": [
+ "retry_non_retriable_status_before_recv_trailing_metadata_started"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+workarounds_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"retry_recv_initial_metadata"
],
"ci_platforms": [
@@ -46215,6 +47096,30 @@
},
{
"args": [
+ "call_host_override"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_http_proxy_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"cancel_after_accept"
],
"ci_platforms": [
@@ -47319,6 +48224,30 @@
},
{
"args": [
+ "retry_non_retriable_status_before_recv_trailing_metadata_started"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_http_proxy_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"retry_recv_initial_metadata"
],
"ci_platforms": [
@@ -47987,6 +48916,29 @@
},
{
"args": [
+ "call_host_override"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_load_reporting_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"cancel_after_accept"
],
"ci_platforms": [
@@ -49026,6 +49978,29 @@
},
{
"args": [
+ "retry_non_retriable_status_before_recv_trailing_metadata_started"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_load_reporting_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"retry_recv_initial_metadata"
],
"ci_platforms": [
@@ -49650,6 +50625,30 @@
},
{
"args": [
+ "call_host_override"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_proxy_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"cancel_after_accept"
],
"ci_platforms": [
@@ -55486,6 +56485,29 @@
},
{
"args": [
+ "retry_non_retriable_status_before_recv_trailing_metadata_started"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_uds_nosec_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"retry_recv_initial_metadata"
],
"ci_platforms": [
@@ -57022,7 +58044,8 @@
"defaults": "boringssl",
"exclude_configs": [
"tsan",
- "asan"
+ "asan",
+ "gcov"
],
"excluded_poll_engines": [],
"flaky": false,
@@ -62840,6 +63863,4836 @@
},
{
"args": [
+ "test/core/security/corpus/alts_credentials_corpus/0149b46b88d583e05be0fb1423d10f2a14d36c48"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/047fc351e73f760d329d5a8845944720be9ce773"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/04ef96c66d8222d1a2c07e6b2a6548e6a527042b"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/05a7e16c1d7f92111f43e9c777421879920e79a4"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/063eb46f202fdfe7935c30ca38d7eb81c82db419"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/064773597c295fa871c184fc12d17b6de8aab31b"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/087449740758b114d16790067707934479946bd6"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/0a5d068feb57a2782c6eba57b637abe8668ac82f"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/0b81e6d89bf7df80e87e5ee7c49f7cc1431f77e8"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/11409339cec708a5e353893101bfe76364337d5c"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/147696a264cd6f197adb7c68aff834c30b1b77f8"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/160e5cac38c5c9e919ed6e4fbafee76907d63044"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/173d02167db431040b0540d98f6fc5e8b456587d"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/18a3fe239806b3c7d1af24bcd2bd23aeeb072d5c"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/195abd83b2e9d32b1b5b854fe33da44b6db40880"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/19af2509c7d84334b9ec64de4767a07d5294fd72"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/1b9864b948fcf08b062fd4401ef55b214c259535"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/1edddfa67de854d7faaba41418fda845e9c6a89d"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/20031bb00e6608e1b570aa96e6afb9de06d42167"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/22b4c7ce7db99b0df63c9eae9265de484b695922"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/27416437ad287bd3cc1c5efdecebc39f20df73c1"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/27e8cd785c2b9346f68dba75761b52fbabaf2b72"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/28236f860d3d8e5ea11176746cb4c1c5c4f1f6c0"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/29e15b492c5a409938092a30c003c5c34df7e283"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/2a47864d77749aa042b772895dbdf46f608ccc6d"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/2cca5cb1b135c35f6e5e1ec4c37deb9e12d37dc0"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/2df27b6c42dbaee382a29a87338d64ee87354acb"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/2e9ddd1339d8e599cef658a08965985c4f45e428"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/31a2d12a84a7a56ace831a9668d6ab4847390679"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/33cb9ec0ce3538ed6079b5fcb127649a5d05955b"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/348d9ae6eebb2e1644addf7f07231d108cf6f3b8"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/359f76f3c802292e92b0640de2bfe051e780a3b6"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/35a479988e965a6e3e75138b64b0bd1f45073e2f"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/362b00d713686ff70cb0199f3d7d0058e5a1a27a"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/3849c1625071791ceae709b9c6c705b28d099d67"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/39ef03c66ee2d4bcfb6c8da50486dcd40f02fb12"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/3a3ca061863499ebc171a4f910fa1b49523baad4"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/3a890f3fd01b048ac9db65a9a9b4f4443268b91a"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/3b9554038a425bd1fae057ba41f9366bb467e946"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/3ce0ae4aa226f205a3a4e66bbb253419d9d754bf"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/3dccc5523986c37e27684659bba8a1037e7a92e8"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/3e0908c15b1cede4541d25f388b1345e8641e221"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/3fcb181ff6a8c8e2ba38ed34cf78f7482eb55cb7"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/41c9b5f720eb8f8fa04c840375a881781a849b43"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/4257a018f08f13a3a9adc848ef808e1be50bc4cf"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/42dfc5c4d13261b7259e65cd692df9c9d607194e"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/43144664aedb585d45d42aa5249ddbfe81afe470"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/43e5ad495a47593b17dbcbd3e70c2e25a417bb6e"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/446614e45b7bef49118b17e031c48faf167ebe3e"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/46492477fa84ca88e85df914801af0b09b0939f6"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/47157f83b166b57e0052c98a65c6db864fa6cb9b"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/473fc9b6d768a925527d3ad805ca363d490dc741"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/483c0b4015100eee00f6b23d1100d8c4953dd3b1"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/48be2dc4cdc5462407b319caa855d976cda88153"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/4e84eb54a0e438052b0c2e83653135042d9eb59a"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/50839d5c8bf33f0970986dcc4b73b024f11a95b7"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/523d964986d8ad966ae07e540a608681098813f9"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/5410b8190c95dacd36d6e6ec75b7538a630e08de"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/549b2891ac79f504a7c9ea00f6d7527c34ce04e6"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/55321649e7b7f1b5664ae20724e683c930643fc4"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/55cc52f25865baee3e6e52c3110a9723caa2b3cb"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/56c22410e3295ad03aa31552ab888f581756cc17"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/5724a705b62a7548ba2df1abe4ef0c970c4e1bd2"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/576a148c107d56861d1611641a6f7c7921061c5c"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/5a6b8263e8939f851cf5b1e347a33d97253b7b3d"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/5ba93c9db0cff93f52b521d7420e43f6eda2784f"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/5bd02a339fd7705449388580c75bfcc597aba954"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/5bd6fb6fc4163bf3a9db6ddaf509dce8df8a5000"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/5d06fc38005503af3d084721c60e574fb9d2f370"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/5ddc10489ff3269bdaa3051b70fb7af455ee1104"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/5ea9d515f0d10b04f1356b9463139bfe121a6e4a"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/61c449793347cf2e1ed0c38d54d23c63dfaabeb8"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/6287389c373e9788dcc04f9747b4be1fd1ef3028"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/64d4de4d5aafab7ec388a7fe83066c1a4d1d9d68"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/651c37806d2ac579dcfc97643c3c1ea74dbb8774"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/6551d02d20573cfa2944ec1f12b0c01f264a1326"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/65f029414ee10e45ff4b9f305f7b472364cea538"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/68b75a17fe2db060df3e61a597650ba99079abbf"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/69e80594dbc5c4c648e39883a650b1760f20ab63"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/6cb47d0e640b4c41e32f13c0d64ee46eae1b80b5"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/6da5fe063432cb9094c7c083efdbbe5ba4246d18"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/6dd140da774d85f272fb587dc1b2a85d881a7c21"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/6ddab273597d73be49e2307d68e00fa18bba4765"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/6eaf85d84fbf47ea0619d0dba8d366f4e3ff0be6"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/6f751cc09af8113f6ecd491b1830bd8454c4738d"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/70d9eb29a70d483d07e2faca6b00098af78d1fff"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/7192effa1058382b379fb7b87f1acad5ac554d05"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/730e85d6a62e70cb6721009b903782ade4ff73a2"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/74002471a854059cb29de7cad8f9fb7adc3c5ec2"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/747f2330cd1fc4a06d54b376a9a6528d0364f0ac"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/749d5d7a9e0b1545b297117e834462af32b3e230"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/77de0b1de120ac702ca45868b1008a48626daf12"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/792c67398bce19a4eeda32653c994436e79456e5"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/7a3022b248c8960289e4c80c7cc8df409499e5da"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/7a9372081294a6fbd3fecdd91b99589c98d4948e"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/7bbe4ba828947550f4ad089d5989cb695ecbdb1b"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/7f1ad514a96f0c3d5ca5d6f7880b929a65eeae96"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/7f2b075f0b6707c38db851747e2578343eeab286"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/81ebc64bfde3fad37af5a58ef7f1c5c3c54c4b5d"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/82fae081afaea13831404024d39658344d56e1c6"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/83ba41cea1adab707f7f213af5e2ed734bdddc25"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/841a3f66c94e5acd836a44cd5a8514d4ad45d83e"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/841ef94ee0f1b0b45983d95b75aba25421d73f2c"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/843b0aad4a9707c5dcc92d12d876b78675cfcb65"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/8483e3d92eda8df504b1d1d0d012f4bcd778cd33"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/876830fdff4e59038fa2173b700faef5bffe61de"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/87ca3342fdce0c1f678a3f1b62428032ef51442d"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/87d044027cdb7d35fadb56532f497764246946a6"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/88ce75ba18bdb7e93a81197d850f4e792f6a8155"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/89dc55e8e20e811e78c952c8bd2c16f55fe72f57"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/8a215a58908f44bdced595ceb01a81977f1d72f0"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/8ac7459e918304ca40b1cf29a3ac0f555eada678"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/8b93e50a911f3ea0e0b0377ba4636574f2ee9a5e"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/8c9ec0ffd803505772693833d56e7a02110645b3"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/8e4b361a530dc6825afcfb4106bd482c3fd010fa"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/8f6690d97bcda890f2a5b2930a2b7a4d7b56c6e7"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/917636de2c14dce2580d4308249a94d61d62c305"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/91f11008defda918951bda868cc68c6373fb0e6a"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/92e01a34047b660a798086d55a3d8d7100a01939"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/963fafadb4de09dee0e6a852bd61b1740039a465"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/97bf33ec97b93fcc2449431915911a55b906e3b6"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/99e31e12b02b02479d10b2c08426906bd93a0840"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/9a75ce693e7259d4d3bb9203dfc0a65f8bbaa466"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/9ac0d956f9743e026baad7319ba2a75d9f1a534f"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/9ae56d4451dd3e1b66ddc250d84dbf6d8cae0dbd"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/9b9a3a1e4023c9b172060249752a482a3437ef2a"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/9c81164e10bf612c352dca3ecabf57743b451d42"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/9d8b420b5d32deb0140ab91eeebba58ca6163722"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/9de687bf1e2cfac54c3b2e2eb85b53014a460ff7"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/9f3cda19a186bd11bfac361b464f92daa129a33b"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/a14fc6a608121f8abf0fe25cf466720f00f25653"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/a39906074669a6b76a35b0adf2bf36ad751f3b35"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/a454ca483b4a66b83826d061be2859dd79ff0d6c"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/a52df5607370ff0f56d821000f3d5e386a01d489"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/a56eaf47f7c7263e53efdc55ec39063dbb4ae71c"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/a79249fb8f7d53f0a280359d2d9df31594adbdfc"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/aa98a46f25004f7436aadb36ff8b7f07ed7bfce1"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/adc83b19e793491b1c6ea0fd8b46cd9f32e592fc"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/afd8e19f7bfd6c963f1856be59b75627864821dc"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/b3966239b8568442baecbeb0f8a1aa29dcdfd7ed"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/b430d41ef65493b3e917182c23ce90df983e01ab"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/b44e715e0cfe05f0c92a9e000ac3c36aae17df9d"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/b4cf4ef7b3f64eff76cf99091fddc04411774708"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/b53d84468ea93620a9824ca65acf1179f431e763"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/b6ac4831cc5baabee9c8ab9af9ca3923f91097a0"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/b7f4a484866a8050dbc63bc905c9803c6964eda5"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/b8f21e59f90431c982d5ec3fb54ae4605f102252"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/bad10b6581cdead8e7cb96e4f544dcf0ea650fbc"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/bb01bed86b43257be9f527388e1183f52438c473"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/bb7497b00f0d999ef39dbf81c6bd0441e32723b6"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/bf01b72e635deda1b4a8468f1cc36f01a54e1338"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/bf8b4530d8d246dd74ac53a13471bba17941dff7"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/c08bc84ab6a512b901bb730beb05c8394e4f1c5d"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/c244b635d94e6f5d6b344887434be3e001a04b41"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/c281efe9620da999a637ff6e9b3279ec613fb992"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/c30a212824ee71e215f475f453de17c65a200101"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/c449427f35b7ecdf5641073629f7723df52c4cb0"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/c60240cd3b02eb71e2bf5ebd59afa3a5dc9b5e4d"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/c60cdf9c3fb9060838f445b3bc3852b6f81e1e4c"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/c72d0501bacadb45242c553ba292591302f12a6a"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/c739e7b5ad999edbdeffdab672dbc30deb3959a0"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/c7d73b12a7108d82f8dac6d8a6a34f838601aca6"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/ca781e1add632433293e847ae9e71649c217ee5f"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/cc48e916f40e8d69c2d07cfda42c7d3b7fe3447a"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/cca1aff4c08ee4ccbcb6f80e1cd1480a0a093cfd"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/cf6ae8bf1d08d25e235b7bee0839984bbc04edf6"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/cfc52fa086292c699efd7bf41d2fae3deb449536"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/cfe13ef3c6c713a059f231f0001ecec97e2a932d"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/d14026ac6421bca7161024f4e735cb80a1068d01"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/d2fb6e8f7867fc1e2ebe723da2b5246dc9cc6b14"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/d4db7d51bdaa4781cf12c3b59914bad414d2a41e"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/d533da0e7f8c1e39bb025b4d7a89613142a6f54e"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/d5cf489d01a1b847a7aac5dddabff23fdc218e1e"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/d686f8561a249c7c15c78f76a5fceb884286e070"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/d92424daad9d96a40e5ab177e3824c36ef51dc0f"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/db242a11ed88b2b26af46770dd1927d9f35301fb"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/db32eb04db13d58f65f46d262608bd088987c063"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/db39a953317951759e40734de6607a0b4457728e"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/dc5e8f3102456bed90d17303bc4cff1a7e076d5d"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/dd9542bbed8e5dc58da2789edbfb9c38d578d3b4"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/de2ebb1ed324385de500a1a3308846239857c3c7"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/de8ba9158254c1cd84b53df1e4cdf1757b1392f1"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/e1dd260746f50024822a8b729b89545d26decfb8"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/e29add81b20dc570fdc885782689f6dccb1c5fad"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/e2e99af62843cd3b29d50daeb118e58830784da9"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/e46611c5daf99662e1576147c1623409752a1f39"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/e5a1ba11af830e9d2db201c5164f75747a85fe9b"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/e6026ee0badf216b326443a5f708446b2f2e579f"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/e6c7d2c0038fa1f03fc6590a726abc98f4c641f3"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/eafdef6a630bed71bd0e4f3d4a16b5fa0c920651"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/ece985b9b82e27281514d460709d7edf8203ded7"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/edb8f4259f756c2c4bc731f05beaa36f992cf079"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/edce7778c2e1adb81dda3d057a6536759a7cb293"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/ee4040c0dd406dd616c49ed2c37b40478dabfe0f"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/ee69f2b380663d051a70f30fcfce9f79f5341e5a"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/efc6743e47274058771bb6eda1fefa017bde4a95"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/f0038e54162000694d882b1acb80930c807b41d2"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/f1deb9e388c877337dabe92f31b01e2a019a10f4"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/f3a09373e4d3c7310d372089e6deb15d6b22c198"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/f3db7ef6495fa1ac5bb4db293fb38dd59122bb7c"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/f434bb4ceecc573e085d4c3ef453ef01e93d9c89"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/f55bceaad42ddf9d2b37fdfca68255d29a696109"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/f62ca5321428a5d23f3c804fb51eb4e65bc58716"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/f7c6a558b8d0af64db2b139371a7af7068b01b92"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/faa1781e1444bba5b8c677bc5e2a38d023a1ec65"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/fceba33ada1dda05fccedfefd331c9a201f1a2e5"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/fd668bef6fdaf7f3ffd58d8c60ce550476652e60"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/fdf06b928e37e7c4ae59a568b5723ad98bbed6e5"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/fe2fc5d499aeb2762387ef2e3ce939280813dec0"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/security/corpus/alts_credentials_corpus/ff548d368b090409a138e5cc4afc7f43b4a3fbbd"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "alts_credentials_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
"test/core/end2end/fuzzers/api_fuzzer_corpus/00.bin"
],
"ci_platforms": [
@@ -103987,6 +109840,75 @@
},
{
"args": [
+ "test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-api_fuzzer-5406804084260864"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "api_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-api_fuzzer-5471994809155584"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "api_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-api_fuzzer-6609852341157888"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "api_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
"test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-minimized-4688823906729984"
],
"ci_platforms": [
diff --git a/tools/run_tests/helper_scripts/build_python.sh b/tools/run_tests/helper_scripts/build_python.sh
index b809fe0..cdcb2aa 100755
--- a/tools/run_tests/helper_scripts/build_python.sh
+++ b/tools/run_tests/helper_scripts/build_python.sh
@@ -112,10 +112,6 @@
export GRPC_PYTHON_BUILD_WITH_CYTHON=1
export LANG=en_US.UTF-8
-# Default python on the host to fall back to when instantiating e.g. the
-# virtualenv.
-HOST_PYTHON=${HOST_PYTHON:-python}
-
# If ccache is available on Linux, use it.
if [ "$(is_linux)" ]; then
# We're not on Darwin (Mac OS X)
@@ -132,16 +128,16 @@
# Perform build operations #
############################
-# Instnatiate the virtualenv, preferring to do so from the relevant python
-# version. Even if these commands fail (e.g. on Windows due to name conflicts)
-# it's possible that the virtualenv is still usable and we trust the tester to
-# be able to 'figure it out' instead of us e.g. doing potentially expensive and
-# unnecessary error recovery by `rm -rf`ing the virtualenv.
-($PYTHON -m virtualenv "$VENV" ||
- $HOST_PYTHON -m virtualenv -p "$PYTHON" "$VENV" ||
- true)
+# Instantiate the virtualenv from the Python version passed in.
+$PYTHON -m pip install virtualenv
+$PYTHON -m virtualenv "$VENV"
VENV_PYTHON=$(script_realpath "$VENV/$VENV_RELATIVE_PYTHON")
+# See https://github.com/grpc/grpc/issues/14815 for more context. We cannot rely
+# on pip to upgrade itself because if pip is too old, it may not have the required
+# TLS version to run `pip install`.
+curl https://bootstrap.pypa.io/get-pip.py | $VENV_PYTHON
+
# pip-installs the directory specified. Used because on MSYS the vanilla Windows
# Python gets confused when parsing paths.
pip_install_dir() {
@@ -152,7 +148,13 @@
cd "$PWD"
}
-$VENV_PYTHON -m pip install --upgrade pip==9.0.1
+case "$VENV" in
+ *gevent*)
+ $VENV_PYTHON -m pip install gevent
+ ;;
+esac
+
+$VENV_PYTHON -m pip install --upgrade pip==10.0.1
$VENV_PYTHON -m pip install setuptools
$VENV_PYTHON -m pip install cython
$VENV_PYTHON -m pip install six enum34 protobuf futures
diff --git a/tools/run_tests/helper_scripts/run_python.sh b/tools/run_tests/helper_scripts/run_python.sh
index bcfe3a6..2b7321e 100755
--- a/tools/run_tests/helper_scripts/run_python.sh
+++ b/tools/run_tests/helper_scripts/run_python.sh
@@ -22,7 +22,7 @@
ROOT=$(pwd)
-$PYTHON "$ROOT/src/python/grpcio_tests/setup.py" test_lite
+$PYTHON "$ROOT/src/python/grpcio_tests/setup.py" "$2"
mkdir -p "$ROOT/reports"
rm -rf "$ROOT/reports/python-coverage"
diff --git a/tools/run_tests/helper_scripts/run_ruby.sh b/tools/run_tests/helper_scripts/run_ruby.sh
index 4e9c212..03eaeb0 100755
--- a/tools/run_tests/helper_scripts/run_ruby.sh
+++ b/tools/run_tests/helper_scripts/run_ruby.sh
@@ -18,4 +18,7 @@
# change to grpc repo root
cd "$(dirname "$0")/../../.."
+# build grpc_ruby_plugin
+make grpc_ruby_plugin -j8
+
rake
diff --git a/tools/run_tests/helper_scripts/run_ruby_end2end_tests.sh b/tools/run_tests/helper_scripts/run_ruby_end2end_tests.sh
index 1955442..5784745 100755
--- a/tools/run_tests/helper_scripts/run_ruby_end2end_tests.sh
+++ b/tools/run_tests/helper_scripts/run_ruby_end2end_tests.sh
@@ -28,4 +28,5 @@
ruby src/ruby/end2end/grpc_class_init_driver.rb || EXIT_CODE=1
ruby src/ruby/end2end/multiple_killed_watching_threads_driver.rb || EXIT_CODE=1
ruby src/ruby/end2end/load_grpc_with_gc_stress_driver.rb || EXIT_CODE=1
+ruby src/ruby/end2end/client_memory_usage_driver.rb || EXIT_CODE=1
exit $EXIT_CODE
diff --git a/tools/run_tests/interop/android/android_interop_helper.sh b/tools/run_tests/interop/android/android_interop_helper.sh
deleted file mode 100755
index 116549b..0000000
--- a/tools/run_tests/interop/android/android_interop_helper.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/bin/bash
-# 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.
-
-# Helper that runs inside the docker container and builds the APKs and
-# invokes Firebase Test Lab via gcloud.
-
-SERVICE_KEY=$1
-
-gcloud auth activate-service-account --key-file="$SERVICE_KEY" || exit 1
-gcloud config set project grpc-testing || exit 1
-
-rm -rf grpc-java
-git clone https://github.com/grpc/grpc-java.git
-cd grpc-java
-./gradlew install || exit 1
-cd android-interop-testing
-../gradlew assembleDebug
-../gradlew assembleDebugAndroidTest
-
-gcloud firebase test android run \
- --type instrumentation \
- --app app/build/outputs/apk/app-debug.apk \
- --test app/build/outputs/apk/app-debug-androidTest.apk \
- --device model=Nexus6,version=21,locale=en,orientation=portrait
diff --git a/tools/run_tests/interop/android/run_android_tests_on_firebase.sh b/tools/run_tests/interop/android/run_android_tests_on_firebase.sh
deleted file mode 100755
index f6472eb..0000000
--- a/tools/run_tests/interop/android/run_android_tests_on_firebase.sh
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/bin/bash
-# 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.
-
-# Builds the gRPC Android instrumented interop tests inside a docker container
-# and runs them on Firebase Test Lab
-
-DOCKERFILE=tools/dockerfile/interoptest/grpc_interop_android_java/Dockerfile
-DOCKER_TAG=android_interop_test
-SERVICE_KEY=~/android-interops-service-key.json
-HELPER=$(pwd)/tools/run_tests/interop/android/android_interop_helper.sh
-
-docker build -t "$DOCKER_TAG" -f "$DOCKERFILE" .
-
-docker run --interactive --rm \
- --volume="$SERVICE_KEY":/service-key.json:ro \
- --volume="$HELPER":/android_interop_helper.sh:ro \
- $DOCKER_TAG \
- /bin/bash -c "/android_interop_helper.sh /service-key.json"
diff --git a/tools/run_tests/python_utils/upload_rbe_results.py b/tools/run_tests/python_utils/upload_rbe_results.py
new file mode 100644
index 0000000..d302024
--- /dev/null
+++ b/tools/run_tests/python_utils/upload_rbe_results.py
@@ -0,0 +1,182 @@
+#!/usr/bin/env python
+# 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.
+"""Uploads RBE results to BigQuery"""
+
+import argparse
+import os
+import json
+import sys
+import urllib2
+import uuid
+
+gcp_utils_dir = os.path.abspath(
+ os.path.join(os.path.dirname(__file__), '../../gcp/utils'))
+sys.path.append(gcp_utils_dir)
+import big_query_utils
+
+_DATASET_ID = 'jenkins_test_results'
+_DESCRIPTION = 'Test results from master RBE builds on Kokoro'
+# 90 days in milliseconds
+_EXPIRATION_MS = 90 * 24 * 60 * 60 * 1000
+_PARTITION_TYPE = 'DAY'
+_PROJECT_ID = 'grpc-testing'
+_RESULTS_SCHEMA = [
+ ('job_name', 'STRING', 'Name of Kokoro job'),
+ ('build_id', 'INTEGER', 'Build ID of Kokoro job'),
+ ('build_url', 'STRING', 'URL of Kokoro build'),
+ ('test_target', 'STRING', 'Bazel target path'),
+ ('test_case', 'STRING', 'Name of test case'),
+ ('result', 'STRING', 'Test or build result'),
+ ('timestamp', 'TIMESTAMP', 'Timestamp of test run'),
+]
+_TABLE_ID = 'rbe_test_results'
+
+
+def _get_api_key():
+ """Returns string with API key to access ResultStore.
+ Intended to be used in Kokoro envrionment."""
+ api_key_directory = os.getenv('KOKORO_GFILE_DIR')
+ api_key_file = os.path.join(api_key_directory, 'resultstore_api_key')
+ assert os.path.isfile(api_key_file), 'Must add --api_key arg if not on ' \
+ 'Kokoro or Kokoro envrionment is not set up properly.'
+ with open(api_key_file, 'r') as f:
+ return f.read().replace('\n', '')
+
+
+def _get_invocation_id():
+ """Returns String of Bazel invocation ID. Intended to be used in
+ Kokoro envirionment."""
+ bazel_id_directory = os.getenv('KOKORO_ARTIFACTS_DIR')
+ bazel_id_file = os.path.join(bazel_id_directory, 'bazel_invocation_ids')
+ assert os.path.isfile(bazel_id_file), 'bazel_invocation_ids file, written ' \
+ 'by bazel_wrapper.py, expected but not found.'
+ with open(bazel_id_file, 'r') as f:
+ return f.read().replace('\n', '')
+
+
+def _upload_results_to_bq(rows):
+ """Upload test results to a BQ table.
+
+ Args:
+ rows: A list of dictionaries containing data for each row to insert
+ """
+ bq = big_query_utils.create_big_query()
+ big_query_utils.create_partitioned_table(
+ bq,
+ _PROJECT_ID,
+ _DATASET_ID,
+ _TABLE_ID,
+ _RESULTS_SCHEMA,
+ _DESCRIPTION,
+ partition_type=_PARTITION_TYPE,
+ expiration_ms=_EXPIRATION_MS)
+
+ max_retries = 3
+ for attempt in range(max_retries):
+ if big_query_utils.insert_rows(bq, _PROJECT_ID, _DATASET_ID, _TABLE_ID,
+ rows):
+ break
+ else:
+ if attempt < max_retries - 1:
+ print('Error uploading result to bigquery, will retry.')
+ else:
+ print(
+ 'Error uploading result to bigquery, all attempts failed.')
+ sys.exit(1)
+
+
+def _get_resultstore_data(api_key, invocation_id):
+ """Returns dictionary of test results by querying ResultStore API.
+ Args:
+ api_key: String of ResultStore API key
+ invocation_id: String of ResultStore invocation ID to results from
+ """
+ all_actions = []
+ page_token = ''
+ # ResultStore's API returns data on a limited number of tests. When we exceed
+ # that limit, the 'nextPageToken' field is included in the request to get
+ # subsequent data, so keep requesting until 'nextPageToken' field is omitted.
+ while True:
+ req = urllib2.Request(
+ url=
+ 'https://resultstore.googleapis.com/v2/invocations/%s/targets/-/configuredTargets/-/actions?key=%s&pageToken=%s'
+ % (invocation_id, api_key, page_token),
+ headers={
+ 'Content-Type': 'application/json'
+ })
+ results = json.loads(urllib2.urlopen(req).read())
+ all_actions.extend(results['actions'])
+ if 'nextPageToken' not in results:
+ break
+ page_token = results['nextPageToken']
+ return all_actions
+
+
+if __name__ == "__main__":
+ # Arguments are necessary if running in a non-Kokoro envrionment.
+ argp = argparse.ArgumentParser(description='Upload RBE results.')
+ argp.add_argument('--api_key', default='', type=str)
+ argp.add_argument('--invocation_id', default='', type=str)
+ args = argp.parse_args()
+
+ api_key = args.api_key or _get_api_key()
+ invocation_id = args.invocation_id or _get_invocation_id()
+ resultstore_actions = _get_resultstore_data(api_key, invocation_id)
+
+ bq_rows = []
+ for action in resultstore_actions:
+ # Filter out non-test related data, such as build results.
+ if 'testAction' not in action:
+ continue
+ # Some test results contain the fileProcessingErrors field, which indicates
+ # an issue with parsing results individual test cases.
+ if 'fileProcessingErrors' in action:
+ test_cases = [{
+ 'testCase': {
+ 'caseName': str(action['id']['actionId']),
+ 'result': str(action['statusAttributes']['status'])
+ }
+ }]
+ else:
+ test_cases = action['testAction']['testSuite']['tests'][0][
+ 'testSuite']['tests']
+ for test_case in test_cases:
+ if 'errors' in test_case['testCase']:
+ result = 'FAILED'
+ else:
+ result = 'PASSED'
+ bq_rows.append({
+ 'insertId': str(uuid.uuid4()),
+ 'json': {
+ 'job_name':
+ os.getenv('KOKORO_JOB_NAME'),
+ 'build_id':
+ os.getenv('KOKORO_BUILD_NUMBER'),
+ 'build_url':
+ 'https://sponge.corp.google.com/invocation?id=%s' %
+ os.getenv('KOKORO_BUILD_ID'),
+ 'test_target':
+ action['id']['targetId'],
+ 'test_case':
+ test_case['testCase']['caseName'],
+ 'result':
+ result,
+ 'timestamp':
+ action['timing']['startTime'],
+ }
+ })
+ # BigQuery sometimes fails with large uploads, so batch 1,000 rows at a time.
+ for i in range((len(bq_rows) / 1000) + 1):
+ _upload_results_to_bq(bq_rows[i * 1000:(i + 1) * 1000])
diff --git a/tools/run_tests/python_utils/upload_test_results.py b/tools/run_tests/python_utils/upload_test_results.py
index a2dd1c6..09dcd57 100644
--- a/tools/run_tests/python_utils/upload_test_results.py
+++ b/tools/run_tests/python_utils/upload_test_results.py
@@ -74,7 +74,7 @@
build_id = os.getenv('BUILD_ID') or os.getenv('KOKORO_BUILD_NUMBER')
build_url = os.getenv('BUILD_URL')
if os.getenv('KOKORO_BUILD_ID'):
- build_url = 'https://sponge.corp.google.com/invocation?id=%s' % os.getenv(
+ build_url = 'https://source.cloud.google.com/results/invocations/%s' % os.getenv(
'KOKORO_BUILD_ID')
job_name = os.getenv('JOB_BASE_NAME') or os.getenv('KOKORO_JOB_NAME')
diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py
index ba4ab3b..aa58107 100755
--- a/tools/run_tests/run_interop_tests.py
+++ b/tools/run_tests/run_interop_tests.py
@@ -545,13 +545,13 @@
def client_cmd(self, args):
return [
- 'py27/bin/python', 'src/python/grpcio_tests/setup.py',
+ 'py27_native/bin/python', 'src/python/grpcio_tests/setup.py',
'run_interop', '--client', '--args="{}"'.format(' '.join(args))
]
def client_cmd_http2interop(self, args):
return [
- 'py27/bin/python',
+ 'py27_native/bin/python',
'src/python/grpcio_tests/tests/http2/negative_http2_client.py',
] + args
@@ -560,7 +560,7 @@
def server_cmd(self, args):
return [
- 'py27/bin/python', 'src/python/grpcio_tests/setup.py',
+ 'py27_native/bin/python', 'src/python/grpcio_tests/setup.py',
'run_interop', '--server', '--args="{}"'.format(' '.join(args))
]
@@ -637,6 +637,14 @@
'java', 'go', 'python', 'c++'
]
+#TODO: Add c++ when c++ ALTS interop client is ready.
+_LANGUAGES_FOR_ALTS_TEST_CASES = ['java', 'go', 'c++']
+
+#TODO: Add c++ when c++ ALTS interop server is ready.
+_SERVERS_FOR_ALTS_TEST_CASES = ['java', 'go', 'c++']
+
+_TRANSPORT_SECURITY_OPTIONS = ['tls', 'alts', 'insecure']
+
DOCKER_WORKDIR_ROOT = '/var/local/git/grpc'
@@ -691,17 +699,29 @@
return ['bash', '-c', ' '.join(cmdline)]
-def auth_options(language, test_case):
+def compute_engine_creds_required(language, test_case):
+ """Returns True if given test requires access to compute engine creds."""
+ language = str(language)
+ if test_case == 'compute_engine_creds':
+ return True
+ if test_case == 'oauth2_auth_token' and language == 'c++':
+ # C++ oauth2 test uses GCE creds because C++ only supports JWT
+ return True
+ return False
+
+
+def auth_options(language, test_case, service_account_key_file=None):
"""Returns (cmdline, env) tuple with cloud_to_prod_auth test options."""
language = str(language)
cmdargs = []
env = {}
- # TODO(jtattermusch): this file path only works inside docker
- key_filepath = '/root/service_account/GrpcTesting-726eb1347f15.json'
+ if not service_account_key_file:
+ # this file path only works inside docker
+ service_account_key_file = '/root/service_account/GrpcTesting-726eb1347f15.json'
oauth_scope_arg = '--oauth_scope=https://www.googleapis.com/auth/xapi.zoo'
- key_file_arg = '--service_account_key_file=%s' % key_filepath
+ key_file_arg = '--service_account_key_file=%s' % service_account_key_file
default_account_arg = '--default_service_account=830293263384-compute@developer.gserviceaccount.com'
if test_case in ['jwt_token_creds', 'per_rpc_creds', 'oauth2_auth_token']:
@@ -709,7 +729,7 @@
'csharp', 'csharpcoreclr', 'node', 'php', 'php7', 'python',
'ruby', 'nodepurejs'
]:
- env['GOOGLE_APPLICATION_CREDENTIALS'] = key_filepath
+ env['GOOGLE_APPLICATION_CREDENTIALS'] = service_account_key_file
else:
cmdargs += [key_file_arg]
@@ -738,22 +758,24 @@
def cloud_to_prod_jobspec(language,
test_case,
- server_host_name,
- server_host_detail,
+ server_host_nickname,
+ server_host,
docker_image=None,
auth=False,
- manual_cmd_log=None):
+ manual_cmd_log=None,
+ service_account_key_file=None):
"""Creates jobspec for cloud-to-prod interop test"""
container_name = None
cmdargs = [
- '--server_host=%s' % server_host_detail[0],
- '--server_host_override=%s' % server_host_detail[1],
- '--server_port=443', '--use_tls=true',
+ '--server_host=%s' % server_host,
+ '--server_host_override=%s' % server_host, '--server_port=443',
+ '--use_tls=true',
'--test_case=%s' % test_case
]
environ = dict(language.cloud_to_prod_env(), **language.global_env())
if auth:
- auth_cmdargs, auth_env = auth_options(language, test_case)
+ auth_cmdargs, auth_env = auth_options(language, test_case,
+ service_account_key_file)
cmdargs += auth_cmdargs
environ.update(auth_env)
cmdline = bash_cmdline(language.client_cmd(cmdargs))
@@ -782,7 +804,7 @@
cmdline=cmdline,
cwd=cwd,
environ=environ,
- shortname='%s:%s:%s:%s' % (suite_name, language, server_host_name,
+ shortname='%s:%s:%s:%s' % (suite_name, language, server_host_nickname,
test_case),
timeout_seconds=_TEST_TIMEOUT,
flake_retries=4 if args.allow_flakes else 0,
@@ -799,14 +821,22 @@
server_host,
server_port,
docker_image=None,
- insecure=False,
+ transport_security='tls',
manual_cmd_log=None):
"""Creates jobspec for cloud-to-cloud interop test"""
interop_only_options = [
'--server_host_override=foo.test.google.fr',
- '--use_tls=%s' % ('false' if insecure else 'true'),
'--use_test_ca=true',
]
+ if transport_security == 'tls':
+ interop_only_options += ['--use_tls=true']
+ elif transport_security == 'alts':
+ interop_only_options += ['--use_tls=false', '--use_alts=true']
+ elif transport_security == 'insecure':
+ interop_only_options += ['--use_tls=false']
+ else:
+ print('Invalid transport security option.')
+ sys.exit(1)
client_test_case = test_case
if test_case in _HTTP2_SERVER_TEST_CASES_THAT_USE_GRPC_CLIENTS:
@@ -871,15 +901,24 @@
return test_job
-def server_jobspec(language, docker_image, insecure=False, manual_cmd_log=None):
+def server_jobspec(language,
+ docker_image,
+ transport_security='tls',
+ manual_cmd_log=None):
"""Create jobspec for running a server"""
container_name = dockerjob.random_name(
'interop_server_%s' % language.safename)
- cmdline = bash_cmdline(
- language.server_cmd([
- '--port=%s' % _DEFAULT_SERVER_PORT,
- '--use_tls=%s' % ('false' if insecure else 'true')
- ]))
+ server_cmd = ['--port=%s' % _DEFAULT_SERVER_PORT]
+ if transport_security == 'tls':
+ server_cmd += ['--use_tls=true']
+ elif transport_security == 'alts':
+ server_cmd += ['--use_tls=false', '--use_alts=true']
+ elif transport_security == 'insecure':
+ server_cmd += ['--use_tls=false']
+ else:
+ print('Invalid transport security option.')
+ sys.exit(1)
+ cmdline = bash_cmdline(language.server_cmd(server_cmd))
environ = language.global_env()
docker_args = ['--name=%s' % container_name]
if language.safename == 'http2':
@@ -984,19 +1023,9 @@
# A dictionary of prod servers to test.
-# Format: server_name: (server_host, server_host_override, errors_allowed)
-# TODO(adelez): implement logic for errors_allowed where if the indicated tests
-# fail, they don't impact the overall test result.
prod_servers = {
- 'default': ('216.239.32.254', 'grpc-test.sandbox.googleapis.com', False),
- 'gateway_v2': ('216.239.32.254', 'grpc-test2.sandbox.googleapis.com', True),
- 'cloud_gateway': ('216.239.32.255', 'grpc-test.sandbox.googleapis.com',
- False),
- 'cloud_gateway_v2': ('216.239.32.255', 'grpc-test2.sandbox.googleapis.com',
- True),
- 'gateway_v4': ('216.239.32.254', 'grpc-test4.sandbox.googleapis.com', True),
- 'cloud_gateway_v4': ('216.239.32.255', 'grpc-test4.sandbox.googleapis.com',
- True),
+ 'default': 'grpc-test.sandbox.googleapis.com',
+ 'gateway_v4': 'grpc-test4.sandbox.googleapis.com',
}
argp = argparse.ArgumentParser(description='Run interop tests.')
@@ -1044,6 +1073,12 @@
'Use servername=HOST:PORT to explicitly specify a server. E.g. csharp=localhost:50000',
default=[])
argp.add_argument(
+ '--service_account_key_file',
+ type=str,
+ help=
+ 'Override the default service account key file to use for auth interop tests.',
+ default=None)
+argp.add_argument(
'-t', '--travis', default=False, action='store_const', const=True)
argp.add_argument(
'-v', '--verbose', default=False, action='store_const', const=True)
@@ -1086,11 +1121,19 @@
'Enable HTTP/2 server edge case testing. (Includes positive and negative tests'
)
argp.add_argument(
- '--insecure',
+ '--transport_security',
+ choices=_TRANSPORT_SECURITY_OPTIONS,
+ default='tls',
+ type=str,
+ nargs='?',
+ const=True,
+ help='Which transport security mechanism to use.')
+argp.add_argument(
+ '--skip_compute_engine_creds',
default=False,
action='store_const',
const=True,
- help='Whether to use secure channel.')
+ help='Skip auth tests requiring access to compute engine credentials.')
argp.add_argument(
'--internal_ci',
default=False,
@@ -1110,6 +1153,9 @@
s
for s in itertools.chain.from_iterable(
_SERVERS if x == 'all' else [x] for x in args.server))
+# ALTS servers are only available for certain languages.
+if args.transport_security == 'alts':
+ servers = servers.intersection(_SERVERS_FOR_ALTS_TEST_CASES)
if args.use_docker:
if not args.travis:
@@ -1139,6 +1185,10 @@
languages = set(_LANGUAGES[l]
for l in itertools.chain.from_iterable(
all_but_objc if x == 'all' else [x] for x in args.language))
+# ALTS interop clients are only available for certain languages.
+if args.transport_security == 'alts':
+ alts_languages = set(_LANGUAGES[l] for l in _LANGUAGES_FOR_ALTS_TEST_CASES)
+ languages = languages.intersection(alts_languages)
languages_http2_clients_for_http2_server_interop = set()
if args.http2_server_interop:
@@ -1207,7 +1257,7 @@
spec = server_jobspec(
_LANGUAGES[lang],
docker_images.get(lang),
- args.insecure,
+ args.transport_security,
manual_cmd_log=server_manual_cmd_log)
if not args.manual_run:
job = dockerjob.DockerJob(spec)
@@ -1235,9 +1285,9 @@
jobs = []
if args.cloud_to_prod:
- if args.insecure:
+ if args.transport_security != 'tls':
print('TLS is always enabled for cloud_to_prod scenarios.')
- for server_host_name in args.prod_servers:
+ for server_host_nickname in args.prod_servers:
for language in languages:
for test_case in _TEST_CASES:
if not test_case in language.unimplemented_test_cases():
@@ -1245,10 +1295,12 @@
test_job = cloud_to_prod_jobspec(
language,
test_case,
- server_host_name,
- prod_servers[server_host_name],
+ server_host_nickname,
+ prod_servers[server_host_nickname],
docker_image=docker_images.get(str(language)),
- manual_cmd_log=client_manual_cmd_log)
+ manual_cmd_log=client_manual_cmd_log,
+ service_account_key_file=args.
+ service_account_key_file)
jobs.append(test_job)
if args.http2_interop:
@@ -1256,28 +1308,34 @@
test_job = cloud_to_prod_jobspec(
http2Interop,
test_case,
- server_host_name,
- prod_servers[server_host_name],
+ server_host_nickname,
+ prod_servers[server_host_nickname],
docker_image=docker_images.get(str(http2Interop)),
- manual_cmd_log=client_manual_cmd_log)
+ manual_cmd_log=client_manual_cmd_log,
+ service_account_key_file=args.service_account_key_file)
jobs.append(test_job)
if args.cloud_to_prod_auth:
- if args.insecure:
+ if args.transport_security != 'tls':
print('TLS is always enabled for cloud_to_prod scenarios.')
- for server_host_name in args.prod_servers:
+ for server_host_nickname in args.prod_servers:
for language in languages:
for test_case in _AUTH_TEST_CASES:
- if not test_case in language.unimplemented_test_cases():
- test_job = cloud_to_prod_jobspec(
- language,
- test_case,
- server_host_name,
- prod_servers[server_host_name],
- docker_image=docker_images.get(str(language)),
- auth=True,
- manual_cmd_log=client_manual_cmd_log)
- jobs.append(test_job)
+ if (not args.skip_compute_engine_creds or
+ not compute_engine_creds_required(
+ language, test_case)):
+ if not test_case in language.unimplemented_test_cases():
+ test_job = cloud_to_prod_jobspec(
+ language,
+ test_case,
+ server_host_nickname,
+ prod_servers[server_host_nickname],
+ docker_image=docker_images.get(str(language)),
+ auth=True,
+ manual_cmd_log=client_manual_cmd_log,
+ service_account_key_file=args.
+ service_account_key_file)
+ jobs.append(test_job)
for server in args.override_server:
server_name = server[0]
@@ -1301,7 +1359,7 @@
server_host,
server_port,
docker_image=docker_images.get(str(language)),
- insecure=args.insecure,
+ transport_security=args.transport_security,
manual_cmd_log=client_manual_cmd_log)
jobs.append(test_job)
@@ -1317,7 +1375,7 @@
server_host,
server_port,
docker_image=docker_images.get(str(http2Interop)),
- insecure=args.insecure,
+ transport_security=args.transport_security,
manual_cmd_log=client_manual_cmd_log)
jobs.append(test_job)
@@ -1353,11 +1411,12 @@
server_port = _DEFAULT_SERVER_PORT + offset
if not args.manual_run:
server_port = http2_server_job.mapped_port(server_port)
- if not args.insecure:
- print((
- 'Creating grpc cient to http2 server test case with insecure connection, even though'
- ' args.insecure is False. Http2 test server only supports insecure connections.'
- ))
+ if args.transport_security != 'insecure':
+ print(
+ ('Creating grpc client to http2 server test case '
+ 'with insecure connection, even though '
+ 'args.transport_security is not insecure. Http2 '
+ 'test server only supports insecure connections.'))
test_job = cloud_to_cloud_jobspec(
language,
test_case,
@@ -1365,7 +1424,7 @@
'localhost',
server_port,
docker_image=docker_images.get(str(language)),
- insecure=True,
+ transport_security='insecure',
manual_cmd_log=client_manual_cmd_log)
jobs.append(test_job)
@@ -1408,12 +1467,6 @@
http2_server_test_cases = (_HTTP2_SERVER_TEST_CASES
if args.http2_server_interop else [])
- report_utils.render_interop_html_report(
- set([str(l) for l in languages]), servers, _TEST_CASES,
- _AUTH_TEST_CASES, _HTTP2_TEST_CASES, http2_server_test_cases, resultset,
- num_failures, args.cloud_to_prod_auth or args.cloud_to_prod,
- args.prod_servers, args.http2_interop)
-
if num_failures:
sys.exit(1)
else:
diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index 85c7f5c..0c270fa 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -204,19 +204,28 @@
_PythonConfigVars = collections.namedtuple('_ConfigVars', [
- 'shell', 'builder', 'builder_prefix_arguments', 'venv_relative_python',
- 'toolchain', 'runner'
+ 'shell',
+ 'builder',
+ 'builder_prefix_arguments',
+ 'venv_relative_python',
+ 'toolchain',
+ 'runner',
+ 'test_name',
+ 'iomgr_platform',
])
def _python_config_generator(name, major, minor, bits, config_vars):
+ name += '_' + config_vars.iomgr_platform
return PythonConfig(
name, config_vars.shell + config_vars.builder +
config_vars.builder_prefix_arguments + [
_python_pattern_function(major=major, minor=minor, bits=bits)
] + [name] + config_vars.venv_relative_python + config_vars.toolchain,
- config_vars.shell + config_vars.runner +
- [os.path.join(name, config_vars.venv_relative_python[0])])
+ config_vars.shell + config_vars.runner + [
+ os.path.join(name, config_vars.venv_relative_python[0]),
+ config_vars.test_name
+ ])
def _pypy_config_generator(name, major, config_vars):
@@ -281,7 +290,7 @@
self._docker_distro, self._make_options = self._compiler_options(
self.args.use_docker, self.args.compiler)
if args.iomgr_platform == "uv":
- cflags = '-DGRPC_UV -DGRPC_CUSTOM_IOMGR_THREAD_CHECK '
+ cflags = '-DGRPC_UV -DGRPC_CUSTOM_IOMGR_THREAD_CHECK -DGRPC_CUSTOM_SOCKET '
try:
cflags += subprocess.check_output(
['pkg-config', '--cflags', 'libuv']).strip() + ' '
@@ -770,12 +779,16 @@
venv_relative_python = ['bin/python']
toolchain = ['unix']
+ test_command = 'test_lite'
+ if args.iomgr_platform == 'gevent':
+ test_command = 'test_gevent'
runner = [
os.path.abspath('tools/run_tests/helper_scripts/run_python.sh')
]
- config_vars = _PythonConfigVars(shell, builder,
- builder_prefix_arguments,
- venv_relative_python, toolchain, runner)
+
+ config_vars = _PythonConfigVars(
+ shell, builder, builder_prefix_arguments, venv_relative_python,
+ toolchain, runner, test_command, args.iomgr_platform)
python27_config = _python_config_generator(
name='py27',
major='2',
@@ -908,9 +921,6 @@
if self.platform == 'mac':
# TODO(jtattermusch): EMBED_ZLIB=true currently breaks the mac build
self._make_options = ['EMBED_OPENSSL=true']
- if self.args.compiler != 'coreclr':
- # On Mac, official distribution of mono is 32bit.
- self._make_options += ['ARCH_FLAGS=-m32', 'LDFLAGS=-m32']
else:
self._make_options = ['EMBED_OPENSSL=true', 'EMBED_ZLIB=true']
@@ -931,6 +941,9 @@
assembly_subdir += '/net45'
if self.platform == 'windows':
runtime_cmd = []
+ elif self.platform == 'mac':
+ # mono before version 5.2 on MacOS defaults to 32bit runtime
+ runtime_cmd = ['mono', '--arch=64']
else:
runtime_cmd = ['mono']
@@ -1341,7 +1354,7 @@
)
argp.add_argument(
'--iomgr_platform',
- choices=['native', 'uv'],
+ choices=['native', 'uv', 'gevent'],
default='native',
help='Selects iomgr platform to build on')
argp.add_argument(
@@ -1407,16 +1420,18 @@
nargs='?',
help='Upload test results to a specified BQ table.')
argp.add_argument(
- '--disable_auto_set_flakes',
+ '--auto_set_flakes',
default=False,
const=True,
action='store_const',
- help='Disable rerunning historically flaky tests')
+ help=
+ 'Allow repeated runs for tests that have been failing recently (based on BQ historical data).'
+)
args = argp.parse_args()
flaky_tests = set()
shortname_to_cpu = {}
-if not args.disable_auto_set_flakes:
+if args.auto_set_flakes:
try:
for test in get_bqtest_data():
if test.flaky: flaky_tests.add(test.name)
diff --git a/tools/run_tests/run_tests_matrix.py b/tools/run_tests/run_tests_matrix.py
index 1c99e79..64d80ab 100755
--- a/tools/run_tests/run_tests_matrix.py
+++ b/tools/run_tests/run_tests_matrix.py
@@ -114,7 +114,7 @@
def _generate_jobs(languages,
configs,
platforms,
- iomgr_platform='native',
+ iomgr_platforms=['native'],
arch=None,
compiler=None,
labels=[],
@@ -125,48 +125,60 @@
result = []
for language in languages:
for platform in platforms:
- for config in configs:
- name = '%s_%s_%s_%s' % (language, platform, config,
- iomgr_platform)
- runtests_args = [
- '-l', language, '-c', config, '--iomgr_platform',
- iomgr_platform
- ]
- if arch or compiler:
- name += '_%s_%s' % (arch, compiler)
- runtests_args += ['--arch', arch, '--compiler', compiler]
- if '--build_only' in extra_args:
- name += '_buildonly'
- for extra_env in extra_envs:
- name += '_%s_%s' % (extra_env, extra_envs[extra_env])
+ for iomgr_platform in iomgr_platforms:
+ for config in configs:
+ name = '%s_%s_%s_%s' % (language, platform, config,
+ iomgr_platform)
+ runtests_args = [
+ '-l', language, '-c', config, '--iomgr_platform',
+ iomgr_platform
+ ]
+ if arch or compiler:
+ name += '_%s_%s' % (arch, compiler)
+ runtests_args += [
+ '--arch', arch, '--compiler', compiler
+ ]
+ if '--build_only' in extra_args:
+ name += '_buildonly'
+ for extra_env in extra_envs:
+ name += '_%s_%s' % (extra_env, extra_envs[extra_env])
- runtests_args += extra_args
- if platform == 'linux':
- job = _docker_jobspec(
- name=name,
- runtests_args=runtests_args,
- runtests_envs=extra_envs,
- inner_jobs=inner_jobs,
- timeout_seconds=timeout_seconds)
- else:
- job = _workspace_jobspec(
- name=name,
- runtests_args=runtests_args,
- runtests_envs=extra_envs,
- inner_jobs=inner_jobs,
- timeout_seconds=timeout_seconds)
+ runtests_args += extra_args
+ if platform == 'linux':
+ job = _docker_jobspec(
+ name=name,
+ runtests_args=runtests_args,
+ runtests_envs=extra_envs,
+ inner_jobs=inner_jobs,
+ timeout_seconds=timeout_seconds)
+ else:
+ job = _workspace_jobspec(
+ name=name,
+ runtests_args=runtests_args,
+ runtests_envs=extra_envs,
+ inner_jobs=inner_jobs,
+ timeout_seconds=timeout_seconds)
- job.labels = [platform, config, language, iomgr_platform
- ] + labels
- result.append(job)
+ job.labels = [platform, config, language, iomgr_platform
+ ] + labels
+ result.append(job)
return result
def _create_test_jobs(extra_args=[], inner_jobs=_DEFAULT_INNER_JOBS):
test_jobs = []
+ # sanity tests
+ test_jobs += _generate_jobs(
+ languages=['sanity'],
+ configs=['dbg', 'opt'],
+ platforms=['linux'],
+ labels=['basictests'],
+ extra_args=extra_args,
+ inner_jobs=inner_jobs)
+
# supported on linux only
test_jobs += _generate_jobs(
- languages=['sanity', 'php7'],
+ languages=['php7'],
configs=['dbg', 'opt'],
platforms=['linux'],
labels=['basictests', 'multilang'],
@@ -184,13 +196,22 @@
timeout_seconds=_CPP_RUNTESTS_TIMEOUT)
test_jobs += _generate_jobs(
- languages=['csharp', 'python'],
+ languages=['csharp'],
configs=['dbg', 'opt'],
platforms=['linux', 'macos', 'windows'],
labels=['basictests', 'multilang'],
extra_args=extra_args,
inner_jobs=inner_jobs)
+ test_jobs += _generate_jobs(
+ languages=['python'],
+ configs=['opt'],
+ platforms=['linux', 'macos', 'windows'],
+ iomgr_platforms=['native', 'gevent'],
+ labels=['basictests', 'multilang'],
+ extra_args=extra_args,
+ inner_jobs=inner_jobs)
+
# supported on linux and mac.
test_jobs += _generate_jobs(
languages=['c++'],
@@ -377,7 +398,7 @@
languages=['c'],
configs=['dbg'],
platforms=['linux'],
- iomgr_platform='uv',
+ iomgr_platforms=['uv'],
labels=['portability', 'corelang'],
extra_args=extra_args,
inner_jobs=inner_jobs,
@@ -508,7 +529,6 @@
extra_args.append('--bq_result_table')
extra_args.append('%s' % args.bq_result_table)
extra_args.append('--measure_cpu_costs')
- extra_args.append('--disable_auto_set_flakes')
all_jobs = _create_test_jobs(extra_args=extra_args, inner_jobs=args.inner_jobs) + \
_create_portability_test_jobs(extra_args=extra_args, inner_jobs=args.inner_jobs)
diff --git a/tools/run_tests/sanity/check_submodules.sh b/tools/run_tests/sanity/check_submodules.sh
index b22bbd6..723d185 100755
--- a/tools/run_tests/sanity/check_submodules.sh
+++ b/tools/run_tests/sanity/check_submodules.sh
@@ -31,7 +31,7 @@
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)
- 2761122b810fe8861004ae785cc3ab39f384d342 third_party/protobuf (v3.5.0)
+ b5fbb742af122b565925987e65c08957739976a7 third_party/protobuf (v3.5.2)
cacf7f1d4e3d44d871b605da3b647f07d718623f third_party/zlib (v1.2.11)
3be1924221e1326df520f8498d704a5c4c8d0cce third_party/cares/cares (cares-1_13_0)
73594cde8c9a52a102c4341c244c833aa61b9c06 third_party/bloaty